| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 //---------------------------------------------------------------------- | 83 //---------------------------------------------------------------------- |
| 84 // GraphicsContext3DInternal | 84 // GraphicsContext3DInternal |
| 85 | 85 |
| 86 GraphicsContext3DInternal::GraphicsContext3DInternal() | 86 GraphicsContext3DInternal::GraphicsContext3DInternal() |
| 87 : m_webViewImpl(0) | 87 : m_webViewImpl(0) |
| 88 , m_initializedAvailableExtensions(false) | 88 , m_initializedAvailableExtensions(false) |
| 89 , m_layerComposited(false) | 89 , m_layerComposited(false) |
| 90 #if USE(SKIA) | 90 #if USE(SKIA) |
| 91 , m_grContext(0) | 91 , m_grContext(0) |
| 92 #elif USE(CG) | 92 #elif USE(CG) |
| 93 , m_renderOutput(0) | 93 , m_renderOutputSize(0) |
| 94 #else | 94 #else |
| 95 #error Must port to your platform | 95 #error Must port to your platform |
| 96 #endif | 96 #endif |
| 97 { | 97 { |
| 98 } | 98 } |
| 99 | 99 |
| 100 GraphicsContext3DInternal::~GraphicsContext3DInternal() | 100 GraphicsContext3DInternal::~GraphicsContext3DInternal() |
| 101 { | 101 { |
| 102 #if USE(CG) | |
| 103 if (m_renderOutput) | |
| 104 delete[] m_renderOutput; | |
| 105 #endif | |
| 106 #if USE(SKIA) | 102 #if USE(SKIA) |
| 107 if (m_grContext) { | 103 if (m_grContext) { |
| 108 m_grContext->contextDestroyed(); | 104 m_grContext->contextDestroyed(); |
| 109 GrSafeUnref(m_grContext); | 105 GrSafeUnref(m_grContext); |
| 110 } | 106 } |
| 111 #endif | 107 #endif |
| 112 } | 108 } |
| 113 | 109 |
| 114 bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs,
HostWindow* hostWindow, bool renderDirectlyToHostWindow) | 110 bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs,
HostWindow* hostWindow, bool renderDirectlyToHostWindow) |
| 115 { | 111 { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 void GraphicsContext3DInternal::markLayerComposited() | 194 void GraphicsContext3DInternal::markLayerComposited() |
| 199 { | 195 { |
| 200 m_layerComposited = true; | 196 m_layerComposited = true; |
| 201 } | 197 } |
| 202 | 198 |
| 203 bool GraphicsContext3DInternal::layerComposited() const | 199 bool GraphicsContext3DInternal::layerComposited() const |
| 204 { | 200 { |
| 205 return m_layerComposited; | 201 return m_layerComposited; |
| 206 } | 202 } |
| 207 | 203 |
| 208 void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingCon
text* context) | 204 void GraphicsContext3DInternal::paintFramebufferToCanvas(int framebuffer, int wi
dth, int height, bool premultiplyAlpha, ImageBuffer* imageBuffer) |
| 209 { | 205 { |
| 210 HTMLCanvasElement* canvas = context->canvas(); | |
| 211 ImageBuffer* imageBuffer = canvas->buffer(); | |
| 212 unsigned char* pixels = 0; | 206 unsigned char* pixels = 0; |
| 207 size_t bufferSize = 4 * width * height; |
| 213 #if USE(SKIA) | 208 #if USE(SKIA) |
| 214 const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bi
tmap(); | 209 const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bi
tmap(); |
| 215 const SkBitmap* readbackBitmap = 0; | 210 const SkBitmap* readbackBitmap = 0; |
| 216 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); | 211 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); |
| 217 if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_
impl->height()) { | 212 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { |
| 218 // This is the fastest and most common case. We read back | 213 // This is the fastest and most common case. We read back |
| 219 // directly into the canvas's backing store. | 214 // directly into the canvas's backing store. |
| 220 readbackBitmap = canvasBitmap; | 215 readbackBitmap = canvasBitmap; |
| 221 m_resizingBitmap.reset(); | 216 m_resizingBitmap.reset(); |
| 222 } else { | 217 } else { |
| 223 // We need to allocate a temporary bitmap for reading back the | 218 // We need to allocate a temporary bitmap for reading back the |
| 224 // pixel data. We will then use Skia to rescale this bitmap to | 219 // pixel data. We will then use Skia to rescale this bitmap to |
| 225 // the size of the canvas's backing store. | 220 // the size of the canvas's backing store. |
| 226 if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.heig
ht() != m_impl->height()) { | 221 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { |
| 227 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, | 222 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 228 m_impl->width(), | 223 width, |
| 229 m_impl->height()); | 224 height); |
| 230 if (!m_resizingBitmap.allocPixels()) | 225 if (!m_resizingBitmap.allocPixels()) |
| 231 return; | 226 return; |
| 232 } | 227 } |
| 233 readbackBitmap = &m_resizingBitmap; | 228 readbackBitmap = &m_resizingBitmap; |
| 234 } | 229 } |
| 235 | 230 |
| 236 // Read back the frame buffer. | 231 // Read back the frame buffer. |
| 237 SkAutoLockPixels bitmapLock(*readbackBitmap); | 232 SkAutoLockPixels bitmapLock(*readbackBitmap); |
| 238 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); | 233 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); |
| 239 #elif USE(CG) | 234 #elif USE(CG) |
| 240 if (m_renderOutput) | 235 if (!m_renderOutput || m_renderOutputSize != bufferSize) { |
| 241 pixels = m_renderOutput; | 236 m_renderOutput = adoptArrayPtr(new unsigned char[bufferSize]); |
| 237 m_renderOutputSize = bufferSize; |
| 238 } |
| 239 |
| 240 pixels = m_renderOutput.get(); |
| 242 #else | 241 #else |
| 243 #error Must port to your platform | 242 #error Must port to your platform |
| 244 #endif | 243 #endif |
| 245 | 244 |
| 246 m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height()); | 245 m_impl->readBackFramebuffer(pixels, 4 * width * height, framebuffer, width,
height); |
| 247 | 246 |
| 248 if (!m_impl->getContextAttributes().premultipliedAlpha) { | 247 if (premultiplyAlpha) { |
| 249 size_t bufferSize = 4 * m_impl->width() * m_impl->height(); | |
| 250 | |
| 251 for (size_t i = 0; i < bufferSize; i += 4) { | 248 for (size_t i = 0; i < bufferSize; i += 4) { |
| 252 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | 249 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); |
| 253 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | 250 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); |
| 254 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | 251 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); |
| 255 } | 252 } |
| 256 } | 253 } |
| 257 | 254 |
| 258 #if USE(SKIA) | 255 #if USE(SKIA) |
| 259 readbackBitmap->notifyPixelsChanged(); | 256 readbackBitmap->notifyPixelsChanged(); |
| 260 if (m_resizingBitmap.readyToDraw()) { | 257 if (m_resizingBitmap.readyToDraw()) { |
| 261 // We need to draw the resizing bitmap into the canvas's backing store. | 258 // We need to draw the resizing bitmap into the canvas's backing store. |
| 262 SkCanvas canvas(*canvasBitmap); | 259 SkCanvas canvas(*canvasBitmap); |
| 263 SkRect dst; | 260 SkRect dst; |
| 264 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); | 261 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); |
| 265 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); | 262 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); |
| 266 } | 263 } |
| 267 #elif USE(CG) | 264 #elif USE(CG) |
| 268 if (m_renderOutput && context->is3d()) { | 265 GraphicsContext3D::paintToCanvas(pixels, width, height, imageBuffer->width()
, imageBuffer->height(), imageBuffer->context()->platformContext()); |
| 269 WebGLRenderingContext* webGLContext = static_cast<WebGLRenderingContext*
>(context); | |
| 270 webGLContext->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl-
>width(), m_impl->height(), canvas->width(), canvas->height(), imageBuffer->cont
ext()->platformContext()); | |
| 271 } | |
| 272 #else | 266 #else |
| 273 #error Must port to your platform | 267 #error Must port to your platform |
| 274 #endif | 268 #endif |
| 275 } | 269 } |
| 276 | 270 |
| 271 void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingCon
text* context) |
| 272 { |
| 273 ImageBuffer* imageBuffer = context->canvas()->buffer(); |
| 274 paintFramebufferToCanvas(0, m_impl->width(), m_impl->height(), !m_impl->getC
ontextAttributes().premultipliedAlpha, imageBuffer); |
| 275 } |
| 276 |
| 277 bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingCo
ntext* context) |
| 278 { |
| 279 #if USE(ACCELERATED_COMPOSITING) |
| 280 if (platformLayer()) |
| 281 return platformLayer()->paintRenderedResultsToCanvas(context->canvas()->
buffer()); |
| 282 #endif |
| 283 return false; |
| 284 } |
| 285 |
| 277 PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageDat
a() | 286 PassRefPtr<ImageData> GraphicsContext3DInternal::paintRenderingResultsToImageDat
a() |
| 278 { | 287 { |
| 279 if (m_impl->getContextAttributes().premultipliedAlpha) | 288 if (m_impl->getContextAttributes().premultipliedAlpha) |
| 280 return 0; | 289 return 0; |
| 281 | 290 |
| 282 RefPtr<ImageData> imageData = ImageData::create(IntSize(m_impl->width(), m_i
mpl->height())); | 291 RefPtr<ImageData> imageData = ImageData::create(IntSize(m_impl->width(), m_i
mpl->height())); |
| 283 unsigned char* pixels = imageData->data()->data()->data(); | 292 unsigned char* pixels = imageData->data()->data()->data(); |
| 284 size_t bufferSize = 4 * m_impl->width() * m_impl->height(); | 293 size_t bufferSize = 4 * m_impl->width() * m_impl->height(); |
| 285 | 294 |
| 286 m_impl->readBackFramebuffer(pixels, bufferSize); | 295 m_impl->readBackFramebuffer(pixels, bufferSize, 0, m_impl->width(), m_impl->
height()); |
| 287 | 296 |
| 288 for (size_t i = 0; i < bufferSize; i += 4) | 297 for (size_t i = 0; i < bufferSize; i += 4) |
| 289 std::swap(pixels[i], pixels[i + 2]); | 298 std::swap(pixels[i], pixels[i + 2]); |
| 290 | 299 |
| 291 return imageData.release(); | 300 return imageData.release(); |
| 292 } | 301 } |
| 293 | 302 |
| 294 bool GraphicsContext3DInternal::paintsIntoCanvasBuffer() const | 303 bool GraphicsContext3DInternal::paintsIntoCanvasBuffer() const |
| 295 { | 304 { |
| 296 // If the gpu compositor is on then skip the readback and software rendering
path. | 305 // If the gpu compositor is on then skip the readback and software rendering
path. |
| 297 return !m_webViewImpl->isAcceleratedCompositingActive(); | 306 return !m_webViewImpl->isAcceleratedCompositingActive(); |
| 298 } | 307 } |
| 299 | 308 |
| 300 void GraphicsContext3DInternal::reshape(int width, int height) | 309 void GraphicsContext3DInternal::reshape(int width, int height) |
| 301 { | 310 { |
| 302 if (width == m_impl->width() && height == m_impl->height()) | 311 if (width == m_impl->width() && height == m_impl->height()) |
| 303 return; | 312 return; |
| 304 | 313 |
| 305 m_impl->reshape(width, height); | 314 m_impl->reshape(width, height); |
| 306 | |
| 307 #if USE(CG) | |
| 308 // Need to reallocate the client-side backing store. | |
| 309 // FIXME: make this more efficient. | |
| 310 if (m_renderOutput) { | |
| 311 delete[] m_renderOutput; | |
| 312 m_renderOutput = 0; | |
| 313 } | |
| 314 int rowBytes = width * 4; | |
| 315 m_renderOutput = new unsigned char[height * rowBytes]; | |
| 316 #endif // USE(CG) | |
| 317 } | 315 } |
| 318 | 316 |
| 319 IntSize GraphicsContext3DInternal::getInternalFramebufferSize() const | 317 IntSize GraphicsContext3DInternal::getInternalFramebufferSize() const |
| 320 { | 318 { |
| 321 return IntSize(m_impl->width(), m_impl->height()); | 319 return IntSize(m_impl->width(), m_impl->height()); |
| 322 } | 320 } |
| 323 | 321 |
| 324 bool GraphicsContext3DInternal::isContextLost() | 322 bool GraphicsContext3DInternal::isContextLost() |
| 325 { | 323 { |
| 326 return m_impl->isContextLost(); | 324 return m_impl->isContextLost(); |
| (...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 DELEGATE_TO_INTERNAL(markLayerComposited) | 1169 DELEGATE_TO_INTERNAL(markLayerComposited) |
| 1172 DELEGATE_TO_INTERNAL(markContextChanged) | 1170 DELEGATE_TO_INTERNAL(markContextChanged) |
| 1173 | 1171 |
| 1174 bool GraphicsContext3D::layerComposited() const | 1172 bool GraphicsContext3D::layerComposited() const |
| 1175 { | 1173 { |
| 1176 return m_internal->layerComposited(); | 1174 return m_internal->layerComposited(); |
| 1177 } | 1175 } |
| 1178 | 1176 |
| 1179 DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, CanvasRenderingContext*) | 1177 DELEGATE_TO_INTERNAL_1(paintRenderingResultsToCanvas, CanvasRenderingContext*) |
| 1180 DELEGATE_TO_INTERNAL_R(paintRenderingResultsToImageData, PassRefPtr<ImageData>) | 1178 DELEGATE_TO_INTERNAL_R(paintRenderingResultsToImageData, PassRefPtr<ImageData>) |
| 1179 DELEGATE_TO_INTERNAL_1R(paintCompositedResultsToCanvas, CanvasRenderingContext*,
bool) |
| 1181 | 1180 |
| 1182 bool GraphicsContext3D::paintsIntoCanvasBuffer() const | 1181 bool GraphicsContext3D::paintsIntoCanvasBuffer() const |
| 1183 { | 1182 { |
| 1184 return m_internal->paintsIntoCanvasBuffer(); | 1183 return m_internal->paintsIntoCanvasBuffer(); |
| 1185 } | 1184 } |
| 1186 | 1185 |
| 1187 DELEGATE_TO_INTERNAL_R(createBuffer, Platform3DObject) | 1186 DELEGATE_TO_INTERNAL_R(createBuffer, Platform3DObject) |
| 1188 DELEGATE_TO_INTERNAL_R(createFramebuffer, Platform3DObject) | 1187 DELEGATE_TO_INTERNAL_R(createFramebuffer, Platform3DObject) |
| 1189 DELEGATE_TO_INTERNAL_R(createProgram, Platform3DObject) | 1188 DELEGATE_TO_INTERNAL_R(createProgram, Platform3DObject) |
| 1190 DELEGATE_TO_INTERNAL_R(createRenderbuffer, Platform3DObject) | 1189 DELEGATE_TO_INTERNAL_R(createRenderbuffer, Platform3DObject) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 | 1257 |
| 1259 void GraphicsContext3DInternal::setSwapBuffersCompleteCallbackCHROMIUM(PassOwnPt
r<Extensions3DChromium::SwapBuffersCompleteCallbackCHROMIUM> cb) | 1258 void GraphicsContext3DInternal::setSwapBuffersCompleteCallbackCHROMIUM(PassOwnPt
r<Extensions3DChromium::SwapBuffersCompleteCallbackCHROMIUM> cb) |
| 1260 { | 1259 { |
| 1261 m_swapBuffersCompleteCallbackAdapter = SwapBuffersCompleteCallbackAdapter::c
reate(cb); | 1260 m_swapBuffersCompleteCallbackAdapter = SwapBuffersCompleteCallbackAdapter::c
reate(cb); |
| 1262 m_impl->setSwapBuffersCompleteCallbackCHROMIUM(m_swapBuffersCompleteCallback
Adapter.get()); | 1261 m_impl->setSwapBuffersCompleteCallbackCHROMIUM(m_swapBuffersCompleteCallback
Adapter.get()); |
| 1263 } | 1262 } |
| 1264 | 1263 |
| 1265 } // namespace WebCore | 1264 } // namespace WebCore |
| 1266 | 1265 |
| 1267 #endif // ENABLE(WEBGL) | 1266 #endif // ENABLE(WEBGL) |
| OLD | NEW |