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 |