Chromium Code Reviews| 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 bool normalized; | 156 bool normalized; |
| 157 unsigned long stride; | 157 unsigned long stride; |
| 158 unsigned long offset; | 158 unsigned long offset; |
| 159 }; | 159 }; |
| 160 | 160 |
| 161 enum { | 161 enum { |
| 162 NumTrackedPointerStates = 2 | 162 NumTrackedPointerStates = 2 |
| 163 }; | 163 }; |
| 164 VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates]; | 164 VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates]; |
| 165 | 165 |
| 166 #if PLATFORM(SKIA) | |
| 167 // If the width and height of the Canvas's backing store don't | |
| 168 // match those that we were given in the most recent call to | |
| 169 // reshape(), then we need an intermediate bitmap to read back the | |
| 170 // frame buffer into. This seems to happen when CSS styles are | |
| 171 // used to resize the Canvas. | |
| 172 SkBitmap* m_resizingBitmap; | |
| 173 #endif | |
| 174 | |
| 166 #if PLATFORM(WIN_OS) | 175 #if PLATFORM(WIN_OS) |
| 167 HWND m_canvasWindow; | 176 HWND m_canvasWindow; |
| 168 HDC m_canvasDC; | 177 HDC m_canvasDC; |
| 169 HGLRC m_contextObj; | 178 HGLRC m_contextObj; |
| 170 #elif PLATFORM(CG) | 179 #elif PLATFORM(CG) |
| 171 CGLPBufferObj m_pbuffer; | 180 CGLPBufferObj m_pbuffer; |
| 172 CGLContextObj m_contextObj; | 181 CGLContextObj m_contextObj; |
| 173 unsigned char* m_renderOutput; | 182 unsigned char* m_renderOutput; |
| 174 CGContextRef m_cgContext; | 183 CGContextRef m_cgContext; |
| 175 #elif PLATFORM(LINUX) | 184 #elif PLATFORM(LINUX) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 217 #endif | 226 #endif |
| 218 | 227 |
| 219 GraphicsContext3DInternal::GraphicsContext3DInternal() | 228 GraphicsContext3DInternal::GraphicsContext3DInternal() |
| 220 : m_texture(0) | 229 : m_texture(0) |
| 221 , m_fbo(0) | 230 , m_fbo(0) |
| 222 , m_depthBuffer(0) | 231 , m_depthBuffer(0) |
| 223 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 232 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
| 224 , m_scanline(NULL) | 233 , m_scanline(NULL) |
| 225 #endif | 234 #endif |
| 226 , m_boundArrayBuffer(0) | 235 , m_boundArrayBuffer(0) |
| 236 #if PLATFORM(SKIA) | |
| 237 , m_resizingBitmap(0) | |
| 238 #endif | |
| 227 #if PLATFORM(WIN_OS) | 239 #if PLATFORM(WIN_OS) |
| 228 , m_canvasWindow(NULL) | 240 , m_canvasWindow(NULL) |
| 229 , m_canvasDC(NULL) | 241 , m_canvasDC(NULL) |
| 230 , m_contextObj(NULL) | 242 , m_contextObj(NULL) |
| 231 #elif PLATFORM(CG) | 243 #elif PLATFORM(CG) |
| 232 , m_pbuffer(NULL) | 244 , m_pbuffer(NULL) |
| 233 , m_contextObj(NULL) | 245 , m_contextObj(NULL) |
| 234 , m_renderOutput(NULL) | 246 , m_renderOutput(NULL) |
| 235 , m_cgContext(NULL) | 247 , m_cgContext(NULL) |
| 236 #elif PLATFORM(LINUX) | 248 #elif PLATFORM(LINUX) |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 makeContextCurrent(); | 480 makeContextCurrent(); |
| 469 #ifndef RENDER_TO_DEBUGGING_WINDOW | 481 #ifndef RENDER_TO_DEBUGGING_WINDOW |
| 470 glDeleteRenderbuffersEXT(1, &m_depthBuffer); | 482 glDeleteRenderbuffersEXT(1, &m_depthBuffer); |
| 471 glDeleteTextures(1, &m_texture); | 483 glDeleteTextures(1, &m_texture); |
| 472 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 484 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
| 473 if (m_scanline != NULL) | 485 if (m_scanline != NULL) |
| 474 delete[] m_scanline; | 486 delete[] m_scanline; |
| 475 #endif | 487 #endif |
| 476 glDeleteFramebuffersEXT(1, &m_fbo); | 488 glDeleteFramebuffersEXT(1, &m_fbo); |
| 477 #endif // !RENDER_TO_DEBUGGING_WINDOW | 489 #endif // !RENDER_TO_DEBUGGING_WINDOW |
| 490 #if PLATFORM(SKIA) | |
| 491 if (m_resizingBitmap) | |
| 492 delete m_resizingBitmap; | |
| 493 #endif | |
| 478 #if PLATFORM(WIN_OS) | 494 #if PLATFORM(WIN_OS) |
| 479 wglMakeCurrent(NULL, NULL); | 495 wglMakeCurrent(NULL, NULL); |
| 480 wglDeleteContext(m_contextObj); | 496 wglDeleteContext(m_contextObj); |
| 481 ReleaseDC(m_canvasWindow, m_canvasDC); | 497 ReleaseDC(m_canvasWindow, m_canvasDC); |
| 482 DestroyWindow(m_canvasWindow); | 498 DestroyWindow(m_canvasWindow); |
| 483 #elif PLATFORM(CG) | 499 #elif PLATFORM(CG) |
| 484 CGLSetCurrentContext(NULL); | 500 CGLSetCurrentContext(NULL); |
| 485 CGLDestroyContext(m_contextObj); | 501 CGLDestroyContext(m_contextObj); |
| 486 CGLDestroyPBuffer(m_pbuffer); | 502 CGLDestroyPBuffer(m_pbuffer); |
| 487 if (m_cgContext != NULL) | 503 if (m_cgContext != NULL) |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 #else | 681 #else |
| 666 // Earlier versions of this code used the GPU to flip the | 682 // Earlier versions of this code used the GPU to flip the |
| 667 // framebuffer vertically before reading it back for compositing | 683 // framebuffer vertically before reading it back for compositing |
| 668 // via software. This code was quite complicated, used a lot of | 684 // via software. This code was quite complicated, used a lot of |
| 669 // GPU memory, and didn't provide an obvious speedup. Since this | 685 // GPU memory, and didn't provide an obvious speedup. Since this |
| 670 // vertical flip is only a temporary solution anyway until Chrome | 686 // vertical flip is only a temporary solution anyway until Chrome |
| 671 // is fully GPU composited, it wasn't worth the complexity. | 687 // is fully GPU composited, it wasn't worth the complexity. |
| 672 | 688 |
| 673 HTMLCanvasElement* canvas = context->canvas(); | 689 HTMLCanvasElement* canvas = context->canvas(); |
| 674 ImageBuffer* imageBuffer = canvas->buffer(); | 690 ImageBuffer* imageBuffer = canvas->buffer(); |
| 675 unsigned char* pixels = NULL; | 691 unsigned char* pixels = 0; |
| 676 #if PLATFORM(SKIA) | 692 #if PLATFORM(SKIA) |
| 677 const SkBitmap& bitmap = *imageBuffer->context()->platformContext()->bitmap(); | 693 const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap(); |
| 678 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); | 694 const SkBitmap* readbackBitmap = 0; |
| 679 ASSERT(bitmap.width() == m_cachedWidth); | 695 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); |
| 680 ASSERT(bitmap.height() == m_cachedHeight); | 696 if (canvasBitmap->width() == m_cachedWidth && |
| 697 canvasBitmap->height() == m_cachedHeight) { | |
| 698 // This is the fastest and most common case. We read back | |
| 699 // directly into the canvas's backing store. | |
| 700 readbackBitmap = canvasBitmap; | |
| 701 if (m_resizingBitmap != NULL) { | |
| 702 delete m_resizingBitmap; | |
| 703 m_resizingBitmap = 0; | |
| 704 } | |
| 705 } else { | |
| 706 // We need to allocate a temporary bitmap for reading back the | |
| 707 // pixel data. We will then use Skia to rescale this bitmap to | |
| 708 // the size of the canvas's backing store. | |
| 709 if (m_resizingBitmap && | |
| 710 (m_resizingBitmap->width() != m_cachedWidth || | |
| 711 m_resizingBitmap->height() != m_cachedHeight)) { | |
| 712 delete m_resizingBitmap; | |
| 713 m_resizingBitmap = 0; | |
| 714 } | |
| 715 if (m_resizingBitmap == 0) { | |
| 716 m_resizingBitmap = new SkBitmap(); | |
| 717 m_resizingBitmap->setConfig(SkBitmap::kARGB_8888_Config, | |
| 718 m_cachedWidth, | |
| 719 m_cachedHeight); | |
| 720 if (!m_resizingBitmap->allocPixels()) { | |
| 721 delete m_resizingBitmap; | |
| 722 m_resizingBitmap = 0; | |
| 723 return; | |
| 724 } | |
| 725 } | |
| 726 readbackBitmap = m_resizingBitmap; | |
| 727 } | |
| 681 | 728 |
| 682 // Read back the frame buffer. | 729 // Read back the frame buffer. |
| 683 SkAutoLockPixels bitmapLock(bitmap); | 730 SkAutoLockPixels bitmapLock(*readbackBitmap); |
| 684 pixels = static_cast<unsigned char*>(bitmap.getPixels()); | 731 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); |
| 685 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); | 732 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); |
| 686 #elif PLATFORM(CG) | 733 #elif PLATFORM(CG) |
| 687 if (m_renderOutput != NULL) { | 734 if (m_renderOutput != NULL) { |
| 688 ASSERT(CGBitmapContextGetWidth(m_cgContext) == m_cachedWidth); | 735 ASSERT(CGBitmapContextGetWidth(m_cgContext) == m_cachedWidth); |
| 689 ASSERT(CGBitmapContextGetHeight(m_cgContext) == m_cachedHeight); | 736 ASSERT(CGBitmapContextGetHeight(m_cgContext) == m_cachedHeight); |
| 690 pixels = m_renderOutput; | 737 pixels = m_renderOutput; |
| 691 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 738 glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
| 692 } | 739 } |
| 693 #else | 740 #else |
| 694 #error Must port to your platform | 741 #error Must port to your platform |
| 695 #endif | 742 #endif |
| 696 | 743 |
| 697 #ifdef FLIP_FRAMEBUFFER_VERTICALLY | 744 #ifdef FLIP_FRAMEBUFFER_VERTICALLY |
| 698 if (pixels != NULL) | 745 if (pixels != NULL) |
| 699 flipVertically(pixels, m_cachedWidth, m_cachedHeight); | 746 flipVertically(pixels, m_cachedWidth, m_cachedHeight); |
| 700 #endif | 747 #endif |
| 701 | 748 |
| 702 #if PLATFORM(SKIA) | 749 #if PLATFORM(SKIA) |
| 703 // No further work necessary | 750 if (m_resizingBitmap) { |
| 751 // We need to draw the resizing bitmap into the canvas's backing store. | |
| 752 SkCanvas canvas(*canvasBitmap); | |
| 753 SkRect dst; | |
| 754 dst.set(0, 0, canvasBitmap->width(), canvasBitmap->height()); | |
| 755 canvas.drawBitmapRect(*m_resizingBitmap, 0, dst); | |
|
brettw
2009/11/03 20:21:18
Do you want antialiasing? This call will not give
| |
| 756 } | |
| 704 #elif PLATFORM(CG) | 757 #elif PLATFORM(CG) |
| 705 if (m_renderOutput != NULL) { | 758 if (m_renderOutput != NULL) { |
| 706 CGImageRef cgImage = CGBitmapContextCreateImage(m_cgContext); | 759 CGImageRef cgImage = CGBitmapContextCreateImage(m_cgContext); |
| 707 CGRect rect = CGRectMake(0, 0, m_cachedWidth, m_cachedHeight); | 760 // CSS styling may cause the canvas's content to be resized on |
| 761 // the page. Go back to the Canvas to figure out the correct | |
| 762 // width and height to draw. | |
| 763 CGRect rect = CGRectMake(0, 0, | |
| 764 context->canvas()->width(), | |
| 765 context->canvas()->height()); | |
| 708 // We want to completely overwrite the previous frame's | 766 // We want to completely overwrite the previous frame's |
| 709 // rendering results. | 767 // rendering results. |
| 710 CGContextSetBlendMode(imageBuffer->context()->platformContext(), | 768 CGContextSetBlendMode(imageBuffer->context()->platformContext(), |
| 711 kCGBlendModeCopy); | 769 kCGBlendModeCopy); |
| 712 CGContextDrawImage(imageBuffer->context()->platformContext(), | 770 CGContextDrawImage(imageBuffer->context()->platformContext(), |
| 713 rect, cgImage); | 771 rect, cgImage); |
| 714 CGImageRelease(cgImage); | 772 CGImageRelease(cgImage); |
| 715 } | 773 } |
| 716 #else | 774 #else |
| 717 #error Must port to your platform | 775 #error Must port to your platform |
| (...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2215 | 2273 |
| 2216 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) | 2274 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) |
| 2217 { | 2275 { |
| 2218 makeContextCurrent(); | 2276 makeContextCurrent(); |
| 2219 m_internal->viewportImpl(x, y, width, height); | 2277 m_internal->viewportImpl(x, y, width, height); |
| 2220 } | 2278 } |
| 2221 | 2279 |
| 2222 } | 2280 } |
| 2223 | 2281 |
| 2224 #endif // ENABLE(3D_CANVAS) | 2282 #endif // ENABLE(3D_CANVAS) |
| OLD | NEW |