Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(913)

Unified Diff: webkit/api/src/GraphicsContext3D.cpp

Issue 342087: Fixed crashes related to incorrect sizing of the Canvas's backing... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/api/src/GraphicsContext3D.cpp
===================================================================
--- webkit/api/src/GraphicsContext3D.cpp (revision 30753)
+++ webkit/api/src/GraphicsContext3D.cpp (working copy)
@@ -163,6 +163,15 @@
};
VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates];
+#if PLATFORM(SKIA)
+ // If the width and height of the Canvas's backing store don't
+ // match those that we were given in the most recent call to
+ // reshape(), then we need an intermediate bitmap to read back the
+ // frame buffer into. This seems to happen when CSS styles are
+ // used to resize the Canvas.
+ SkBitmap* m_resizingBitmap;
+#endif
+
#if PLATFORM(WIN_OS)
HWND m_canvasWindow;
HDC m_canvasDC;
@@ -224,6 +233,9 @@
, m_scanline(NULL)
#endif
, m_boundArrayBuffer(0)
+#if PLATFORM(SKIA)
+ , m_resizingBitmap(0)
+#endif
#if PLATFORM(WIN_OS)
, m_canvasWindow(NULL)
, m_canvasDC(NULL)
@@ -475,6 +487,10 @@
#endif
glDeleteFramebuffersEXT(1, &m_fbo);
#endif // !RENDER_TO_DEBUGGING_WINDOW
+#if PLATFORM(SKIA)
+ if (m_resizingBitmap)
+ delete m_resizingBitmap;
+#endif
#if PLATFORM(WIN_OS)
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_contextObj);
@@ -672,16 +688,47 @@
HTMLCanvasElement* canvas = context->canvas();
ImageBuffer* imageBuffer = canvas->buffer();
- unsigned char* pixels = NULL;
+ unsigned char* pixels = 0;
#if PLATFORM(SKIA)
- const SkBitmap& bitmap = *imageBuffer->context()->platformContext()->bitmap();
- ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
- ASSERT(bitmap.width() == m_cachedWidth);
- ASSERT(bitmap.height() == m_cachedHeight);
+ const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
+ const SkBitmap* readbackBitmap = 0;
+ ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config);
+ if (canvasBitmap->width() == m_cachedWidth &&
+ canvasBitmap->height() == m_cachedHeight) {
+ // This is the fastest and most common case. We read back
+ // directly into the canvas's backing store.
+ readbackBitmap = canvasBitmap;
+ if (m_resizingBitmap != NULL) {
+ delete m_resizingBitmap;
+ m_resizingBitmap = 0;
+ }
+ } else {
+ // We need to allocate a temporary bitmap for reading back the
+ // pixel data. We will then use Skia to rescale this bitmap to
+ // the size of the canvas's backing store.
+ if (m_resizingBitmap &&
+ (m_resizingBitmap->width() != m_cachedWidth ||
+ m_resizingBitmap->height() != m_cachedHeight)) {
+ delete m_resizingBitmap;
+ m_resizingBitmap = 0;
+ }
+ if (m_resizingBitmap == 0) {
+ m_resizingBitmap = new SkBitmap();
+ m_resizingBitmap->setConfig(SkBitmap::kARGB_8888_Config,
+ m_cachedWidth,
+ m_cachedHeight);
+ if (!m_resizingBitmap->allocPixels()) {
+ delete m_resizingBitmap;
+ m_resizingBitmap = 0;
+ return;
+ }
+ }
+ readbackBitmap = m_resizingBitmap;
+ }
// Read back the frame buffer.
- SkAutoLockPixels bitmapLock(bitmap);
- pixels = static_cast<unsigned char*>(bitmap.getPixels());
+ SkAutoLockPixels bitmapLock(*readbackBitmap);
+ pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
#elif PLATFORM(CG)
if (m_renderOutput != NULL) {
@@ -700,11 +747,22 @@
#endif
#if PLATFORM(SKIA)
- // No further work necessary
+ if (m_resizingBitmap) {
+ // We need to draw the resizing bitmap into the canvas's backing store.
+ SkCanvas canvas(*canvasBitmap);
+ SkRect dst;
+ dst.set(0, 0, canvasBitmap->width(), canvasBitmap->height());
+ canvas.drawBitmapRect(*m_resizingBitmap, 0, dst);
brettw 2009/11/03 20:21:18 Do you want antialiasing? This call will not give
+ }
#elif PLATFORM(CG)
if (m_renderOutput != NULL) {
CGImageRef cgImage = CGBitmapContextCreateImage(m_cgContext);
- CGRect rect = CGRectMake(0, 0, m_cachedWidth, m_cachedHeight);
+ // CSS styling may cause the canvas's content to be resized on
+ // the page. Go back to the Canvas to figure out the correct
+ // width and height to draw.
+ CGRect rect = CGRectMake(0, 0,
+ context->canvas()->width(),
+ context->canvas()->height());
// We want to completely overwrite the previous frame's
// rendering results.
CGContextSetBlendMode(imageBuffer->context()->platformContext(),
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698