| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010, Google Inc. All rights reserved. | 2 * Copyright (c) 2010, 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 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 #include "DrawingBuffer.h" | 33 #include "DrawingBuffer.h" |
| 34 | 34 |
| 35 #include "CanvasRenderingContext.h" | 35 #include "CanvasRenderingContext.h" |
| 36 #include "Extensions3D.h" | 36 #include "Extensions3D.h" |
| 37 #include "GraphicsContext3D.h" | 37 #include "GraphicsContext3D.h" |
| 38 #include "GraphicsContext3DPrivate.h" | 38 #include "GraphicsContext3DPrivate.h" |
| 39 #include "GraphicsLayerChromium.h" | 39 #include "GraphicsLayerChromium.h" |
| 40 #include "ImageData.h" | 40 #include "ImageData.h" |
| 41 #include "TraceEvent.h" | 41 #include "TraceEvent.h" |
| 42 #include "WebGLRenderingContext.h" |
| 42 #include <algorithm> | 43 #include <algorithm> |
| 43 #include <public/Platform.h> | 44 #include <public/Platform.h> |
| 44 #include <public/WebCompositorSupport.h> | 45 #include <public/WebCompositorSupport.h> |
| 45 #include <public/WebExternalTextureLayer.h> | 46 #include <public/WebExternalTextureLayer.h> |
| 46 #include <public/WebGraphicsContext3D.h> | 47 #include <public/WebGraphicsContext3D.h> |
| 47 | 48 |
| 48 using namespace std; | 49 using namespace std; |
| 49 | 50 |
| 50 namespace WebCore { | 51 namespace WebCore { |
| 51 | 52 |
| 52 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer crea
tion and resize. | 53 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer crea
tion and resize. |
| 53 // When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() ca
lls that would | 54 // When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() ca
lls that would |
| 54 // exceed the global cap will instead clear the buffer. | 55 // exceed the global cap will instead clear the buffer. |
| 55 static int s_maximumResourceUsePixels = 16 * 1024 * 1024; | 56 static int s_maximumResourceUsePixels = 16 * 1024 * 1024; |
| 56 static int s_currentResourceUsePixels = 0; | 57 static int s_currentResourceUsePixels = 0; |
| 57 static const float s_resourceAdjustedRatio = 0.5; | 58 static const float s_resourceAdjustedRatio = 0.5; |
| 59 static const int s_maxScaleAttempts = 3; |
| 58 | 60 |
| 59 static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize&
size) | 61 static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize&
size) |
| 60 { | 62 { |
| 61 unsigned offscreenColorTexture = context->createTexture(); | 63 unsigned offscreenColorTexture = context->createTexture(); |
| 62 if (!offscreenColorTexture) | 64 if (!offscreenColorTexture) |
| 63 return 0; | 65 return 0; |
| 64 | 66 |
| 65 context->bindTexture(GraphicsContext3D::TEXTURE_2D, offscreenColorTexture); | 67 context->bindTexture(GraphicsContext3D::TEXTURE_2D, offscreenColorTexture); |
| 66 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEX
TURE_MAG_FILTER, GraphicsContext3D::LINEAR); | 68 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEX
TURE_MAG_FILTER, GraphicsContext3D::LINEAR); |
| 67 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEX
TURE_MIN_FILTER, GraphicsContext3D::LINEAR); | 69 context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEX
TURE_MIN_FILTER, GraphicsContext3D::LINEAR); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); | 104 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation"); |
| 103 | 105 |
| 104 // We need a separate front and back textures if ... | 106 // We need a separate front and back textures if ... |
| 105 m_separateFrontTexture = m_preserveDrawingBuffer == Preserve // ... we have
to preserve contents after compositing, which is done with a copy or ... | 107 m_separateFrontTexture = m_preserveDrawingBuffer == Preserve // ... we have
to preserve contents after compositing, which is done with a copy or ... |
| 106 || WebKit::Platform::current()->isThreadedCompositi
ngEnabled(); // ... if we're in threaded mode and need to double buffer. | 108 || WebKit::Platform::current()->isThreadedCompositi
ngEnabled(); // ... if we're in threaded mode and need to double buffer. |
| 107 initialize(size); | 109 initialize(size); |
| 108 } | 110 } |
| 109 | 111 |
| 110 DrawingBuffer::~DrawingBuffer() | 112 DrawingBuffer::~DrawingBuffer() |
| 111 { | 113 { |
| 114 clear(); |
| 115 |
| 112 if (!m_context) | 116 if (!m_context) |
| 113 return; | 117 return; |
| 114 | 118 |
| 115 clear(); | |
| 116 | |
| 117 if (m_layer) | 119 if (m_layer) |
| 118 GraphicsLayerChromium::unregisterContentsLayer(m_layer->layer()); | 120 GraphicsLayerChromium::unregisterContentsLayer(m_layer->layer()); |
| 119 } | 121 } |
| 120 | 122 |
| 121 unsigned DrawingBuffer::prepareTexture(WebKit::WebTextureUpdater& updater) | 123 unsigned DrawingBuffer::prepareTexture(WebKit::WebTextureUpdater& updater) |
| 122 { | 124 { |
| 123 prepareBackBuffer(); | 125 prepareBackBuffer(); |
| 124 | 126 |
| 125 graphicsContext3D()->flush(); | 127 graphicsContext3D()->flush(); |
| 126 graphicsContext3D()->markLayerComposited(); | 128 graphicsContext3D()->markLayerComposited(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 } | 257 } |
| 256 bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth
_stencil"); | 258 bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth
_stencil"); |
| 257 if (packedDepthStencilSupported) | 259 if (packedDepthStencilSupported) |
| 258 extensions->ensureEnabled("GL_OES_packed_depth_stencil"); | 260 extensions->ensureEnabled("GL_OES_packed_depth_stencil"); |
| 259 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, si
ze, multisampleSupported, packedDepthStencilSupported, preserve, alpha)); | 261 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, si
ze, multisampleSupported, packedDepthStencilSupported, preserve, alpha)); |
| 260 return (drawingBuffer->m_context) ? drawingBuffer.release() : 0; | 262 return (drawingBuffer->m_context) ? drawingBuffer.release() : 0; |
| 261 } | 263 } |
| 262 | 264 |
| 263 void DrawingBuffer::clear() | 265 void DrawingBuffer::clear() |
| 264 { | 266 { |
| 265 if (!m_context) | 267 if (m_context) { |
| 266 return; | 268 m_context->makeContextCurrent(); |
| 267 | 269 |
| 268 m_context->makeContextCurrent(); | 270 clearPlatformLayer(); |
| 269 | 271 |
| 270 clearPlatformLayer(); | 272 if (m_colorBuffer) |
| 273 m_context->deleteTexture(m_colorBuffer); |
| 274 |
| 275 if (m_frontColorBuffer) |
| 276 m_context->deleteTexture(m_frontColorBuffer); |
| 277 |
| 278 if (m_multisampleColorBuffer) |
| 279 m_context->deleteRenderbuffer(m_multisampleColorBuffer); |
| 280 |
| 281 if (m_depthStencilBuffer) |
| 282 m_context->deleteRenderbuffer(m_depthStencilBuffer); |
| 283 |
| 284 if (m_depthBuffer) |
| 285 m_context->deleteRenderbuffer(m_depthBuffer); |
| 286 |
| 287 if (m_stencilBuffer) |
| 288 m_context->deleteRenderbuffer(m_stencilBuffer); |
| 289 |
| 290 if (m_multisampleFBO) |
| 291 m_context->deleteFramebuffer(m_multisampleFBO); |
| 292 |
| 293 if (m_fbo) |
| 294 m_context->deleteFramebuffer(m_fbo); |
| 295 } |
| 271 | 296 |
| 272 if (!m_size.isEmpty()) { | 297 if (!m_size.isEmpty()) { |
| 273 s_currentResourceUsePixels -= m_size.width() * m_size.height(); | 298 s_currentResourceUsePixels -= m_size.width() * m_size.height(); |
| 274 m_size = IntSize(); | 299 m_size = IntSize(); |
| 275 } | 300 } |
| 276 | 301 |
| 277 if (m_colorBuffer) { | 302 m_colorBuffer = 0; |
| 278 m_context->deleteTexture(m_colorBuffer); | 303 m_frontColorBuffer = 0; |
| 279 m_colorBuffer = 0; | 304 m_multisampleColorBuffer = 0; |
| 280 } | 305 m_depthStencilBuffer = 0; |
| 281 | 306 m_depthBuffer = 0; |
| 282 if (m_frontColorBuffer) { | 307 m_stencilBuffer = 0; |
| 283 m_context->deleteTexture(m_frontColorBuffer); | 308 m_multisampleFBO = 0; |
| 284 m_frontColorBuffer = 0; | 309 m_fbo = 0; |
| 285 } | |
| 286 | |
| 287 if (m_multisampleColorBuffer) { | |
| 288 m_context->deleteRenderbuffer(m_multisampleColorBuffer); | |
| 289 m_multisampleColorBuffer = 0; | |
| 290 } | |
| 291 | |
| 292 if (m_depthStencilBuffer) { | |
| 293 m_context->deleteRenderbuffer(m_depthStencilBuffer); | |
| 294 m_depthStencilBuffer = 0; | |
| 295 } | |
| 296 | |
| 297 if (m_depthBuffer) { | |
| 298 m_context->deleteRenderbuffer(m_depthBuffer); | |
| 299 m_depthBuffer = 0; | |
| 300 } | |
| 301 | |
| 302 if (m_stencilBuffer) { | |
| 303 m_context->deleteRenderbuffer(m_stencilBuffer); | |
| 304 m_stencilBuffer = 0; | |
| 305 } | |
| 306 | |
| 307 if (m_multisampleFBO) { | |
| 308 m_context->deleteFramebuffer(m_multisampleFBO); | |
| 309 m_multisampleFBO = 0; | |
| 310 } | |
| 311 | |
| 312 if (m_fbo) { | |
| 313 m_context->deleteFramebuffer(m_fbo); | |
| 314 m_fbo = 0; | |
| 315 } | |
| 316 } | 310 } |
| 317 | 311 |
| 318 void DrawingBuffer::createSecondaryBuffers() | 312 void DrawingBuffer::createSecondaryBuffers() |
| 319 { | 313 { |
| 320 // create a multisample FBO | 314 // create a multisample FBO |
| 321 if (multisample()) { | 315 if (multisample()) { |
| 322 m_multisampleFBO = m_context->createFramebuffer(); | 316 m_multisampleFBO = m_context->createFramebuffer(); |
| 323 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisample
FBO); | 317 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisample
FBO); |
| 324 m_multisampleColorBuffer = m_context->createRenderbuffer(); | 318 m_multisampleColorBuffer = m_context->createRenderbuffer(); |
| 325 } | 319 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 | 407 |
| 414 int maxTextureSize = 0; | 408 int maxTextureSize = 0; |
| 415 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize)
; | 409 m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize)
; |
| 416 if (newSize.height() > maxTextureSize || newSize.width() > maxTextureSize) { | 410 if (newSize.height() > maxTextureSize || newSize.width() > maxTextureSize) { |
| 417 clear(); | 411 clear(); |
| 418 return false; | 412 return false; |
| 419 } | 413 } |
| 420 | 414 |
| 421 int pixelDelta = newSize.width() * newSize.height(); | 415 int pixelDelta = newSize.width() * newSize.height(); |
| 422 int oldSize = 0; | 416 int oldSize = 0; |
| 417 bool newBuffer = true; |
| 423 if (!m_size.isEmpty()) { | 418 if (!m_size.isEmpty()) { |
| 424 oldSize = m_size.width() * m_size.height(); | 419 oldSize = m_size.width() * m_size.height(); |
| 425 pixelDelta -= oldSize; | 420 pixelDelta -= oldSize; |
| 421 newBuffer = false; |
| 422 } |
| 423 |
| 424 if(newBuffer && s_currentResourceUsePixels == s_maximumResourceUsePixels) { |
| 425 WebGLRenderingContext::forceLostOldestContext(); |
| 426 newBuffer = false; |
| 426 } | 427 } |
| 427 | 428 |
| 428 IntSize adjustedSize = newSize; | 429 IntSize adjustedSize = newSize; |
| 430 int scaleAttempts = 0; |
| 429 if (s_maximumResourceUsePixels) { | 431 if (s_maximumResourceUsePixels) { |
| 430 while ((s_currentResourceUsePixels + pixelDelta) > s_maximumResourceUseP
ixels) { | 432 while ((s_currentResourceUsePixels + pixelDelta) > s_maximumResourceUseP
ixels) { |
| 431 adjustedSize.scale(s_resourceAdjustedRatio); | 433 adjustedSize.scale(s_resourceAdjustedRatio); |
| 434 |
| 435 scaleAttempts++; |
| 436 if(newBuffer && scaleAttempts >= s_maxScaleAttempts) { |
| 437 WebGLRenderingContext::forceLostOldestContext(); |
| 438 adjustedSize = newSize; |
| 439 newBuffer = false; |
| 440 } |
| 441 |
| 432 if (adjustedSize.isEmpty()) { | 442 if (adjustedSize.isEmpty()) { |
| 433 clear(); | 443 clear(); |
| 434 return false; | 444 return false; |
| 435 } | 445 } |
| 436 pixelDelta = adjustedSize.width() * adjustedSize.height(); | 446 pixelDelta = adjustedSize.width() * adjustedSize.height(); |
| 437 pixelDelta -= oldSize; | 447 pixelDelta -= oldSize; |
| 438 } | 448 } |
| 439 } | 449 } |
| 440 | 450 |
| 441 const GraphicsContext3D::Attributes& attributes = m_context->getContextAttri
butes(); | 451 const GraphicsContext3D::Attributes& attributes = m_context->getContextAttri
butes(); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 | 620 |
| 611 void DrawingBuffer::bind() | 621 void DrawingBuffer::bind() |
| 612 { | 622 { |
| 613 if (!m_context) | 623 if (!m_context) |
| 614 return; | 624 return; |
| 615 | 625 |
| 616 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO
? m_multisampleFBO : m_fbo); | 626 m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO
? m_multisampleFBO : m_fbo); |
| 617 } | 627 } |
| 618 | 628 |
| 619 } // namespace WebCore | 629 } // namespace WebCore |
| OLD | NEW |