Chromium Code Reviews| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 private: | 83 private: |
| 84 gpu::gles2::GLES2Interface* m_gl; | 84 gpu::gles2::GLES2Interface* m_gl; |
| 85 GLenum m_oldActiveTextureUnit; | 85 GLenum m_oldActiveTextureUnit; |
| 86 GLuint m_oldTextureUnitZeroId; | 86 GLuint m_oldTextureUnitZeroId; |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 static bool shouldFailDrawingBufferCreationForTesting = false; | 89 static bool shouldFailDrawingBufferCreationForTesting = false; |
| 90 | 90 |
| 91 } // namespace | 91 } // namespace |
| 92 | 92 |
| 93 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3DP rovider> contextProvider, const IntSize& size, bool premultipliedAlpha, Preserve DrawingBuffer preserve, WebGraphicsContext3D::Attributes requestedAttributes) | 93 PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3DP rovider> contextProvider, const IntSize& size, bool premultipliedAlpha, bool wan tAlphaChannel, bool wantDepthBuffer, bool wantStencilBuffer, bool wantAntialiasi ng, PreserveDrawingBuffer preserve) |
| 94 { | 94 { |
| 95 ASSERT(contextProvider); | 95 ASSERT(contextProvider); |
| 96 | 96 |
| 97 if (shouldFailDrawingBufferCreationForTesting) { | 97 if (shouldFailDrawingBufferCreationForTesting) { |
| 98 shouldFailDrawingBufferCreationForTesting = false; | 98 shouldFailDrawingBufferCreationForTesting = false; |
| 99 return nullptr; | 99 return nullptr; |
| 100 } | 100 } |
| 101 | 101 |
| 102 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(contextPr ovider->contextGL()); | 102 OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(contextPr ovider->contextGL()); |
| 103 if (!extensionsUtil->isValid()) { | 103 if (!extensionsUtil->isValid()) { |
| 104 // This might be the first time we notice that the GL context is lost. | 104 // This might be the first time we notice that the GL context is lost. |
| 105 return nullptr; | 105 return nullptr; |
| 106 } | 106 } |
| 107 ASSERT(extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil")); | 107 ASSERT(extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil")); |
| 108 extensionsUtil->ensureExtensionEnabled("GL_OES_packed_depth_stencil"); | 108 extensionsUtil->ensureExtensionEnabled("GL_OES_packed_depth_stencil"); |
| 109 bool multisampleSupported = (extensionsUtil->supportsExtension("GL_CHROMIUM_ framebuffer_multisample") | 109 bool multisampleSupported = wantAntialiasing |
| 110 || extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_text ure")) | 110 && (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisamp le") |
| 111 || extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_ texture")) | |
| 111 && extensionsUtil->supportsExtension("GL_OES_rgb8_rgba8"); | 112 && extensionsUtil->supportsExtension("GL_OES_rgb8_rgba8"); |
| 112 if (multisampleSupported) { | 113 if (multisampleSupported) { |
| 113 extensionsUtil->ensureExtensionEnabled("GL_OES_rgb8_rgba8"); | 114 extensionsUtil->ensureExtensionEnabled("GL_OES_rgb8_rgba8"); |
| 114 if (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisamp le")) | 115 if (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisamp le")) |
| 115 extensionsUtil->ensureExtensionEnabled("GL_CHROMIUM_framebuffer_mult isample"); | 116 extensionsUtil->ensureExtensionEnabled("GL_CHROMIUM_framebuffer_mult isample"); |
| 116 else | 117 else |
| 117 extensionsUtil->ensureExtensionEnabled("GL_EXT_multisampled_render_t o_texture"); | 118 extensionsUtil->ensureExtensionEnabled("GL_EXT_multisampled_render_t o_texture"); |
| 118 } | 119 } |
| 119 bool discardFramebufferSupported = extensionsUtil->supportsExtension("GL_EXT _discard_framebuffer"); | 120 bool discardFramebufferSupported = extensionsUtil->supportsExtension("GL_EXT _discard_framebuffer"); |
| 120 if (discardFramebufferSupported) | 121 if (discardFramebufferSupported) |
| 121 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 122 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); |
| 122 | 123 |
| 123 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(c ontextProvider), extensionsUtil.release(), multisampleSupported, discardFramebuf ferSupported, premultipliedAlpha, preserve, requestedAttributes)); | 124 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(c ontextProvider), extensionsUtil.release(), discardFramebufferSupported, wantAlph aChannel, premultipliedAlpha, preserve)); |
| 124 if (!drawingBuffer->initialize(size)) { | 125 if (!drawingBuffer->initialize(size, wantDepthBuffer, wantStencilBuffer, mul tisampleSupported)) { |
| 125 drawingBuffer->beginDestruction(); | 126 drawingBuffer->beginDestruction(); |
| 126 return PassRefPtr<DrawingBuffer>(); | 127 return PassRefPtr<DrawingBuffer>(); |
| 127 } | 128 } |
| 128 return drawingBuffer.release(); | 129 return drawingBuffer.release(); |
| 129 } | 130 } |
| 130 | 131 |
| 131 void DrawingBuffer::forceNextDrawingBufferCreationToFail() | 132 void DrawingBuffer::forceNextDrawingBufferCreationToFail() |
| 132 { | 133 { |
| 133 shouldFailDrawingBufferCreationForTesting = true; | 134 shouldFailDrawingBufferCreationForTesting = true; |
| 134 } | 135 } |
| 135 | 136 |
| 136 DrawingBuffer::DrawingBuffer(PassOwnPtr<WebGraphicsContext3DProvider> contextPro vider, PassOwnPtr<Extensions3DUtil> extensionsUtil, bool multisampleExtensionSup ported, bool discardFramebufferSupported, bool premultipliedAlpha, PreserveDrawi ngBuffer preserve, WebGraphicsContext3D::Attributes requestedAttributes) | 137 DrawingBuffer::DrawingBuffer( |
| 138 PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, | |
| 139 PassOwnPtr<Extensions3DUtil> extensionsUtil, | |
| 140 bool discardFramebufferSupported, | |
| 141 bool wantAlphaChannel, | |
| 142 bool premultipliedAlpha, | |
| 143 PreserveDrawingBuffer preserve) | |
| 137 : m_preserveDrawingBuffer(preserve) | 144 : m_preserveDrawingBuffer(preserve) |
| 138 , m_scissorEnabled(false) | 145 , m_scissorEnabled(false) |
| 139 , m_texture2DBinding(0) | 146 , m_texture2DBinding(0) |
| 140 , m_drawFramebufferBinding(0) | 147 , m_drawFramebufferBinding(0) |
| 141 , m_readFramebufferBinding(0) | 148 , m_readFramebufferBinding(0) |
| 142 , m_activeTextureUnit(GL_TEXTURE0) | 149 , m_activeTextureUnit(GL_TEXTURE0) |
| 143 , m_contextProvider(std::move(contextProvider)) | 150 , m_contextProvider(std::move(contextProvider)) |
| 144 , m_context(m_contextProvider->context3d()) | 151 , m_context(m_contextProvider->context3d()) |
| 145 , m_gl(m_contextProvider->contextGL()) | 152 , m_gl(m_contextProvider->contextGL()) |
| 146 , m_extensionsUtil(std::move(extensionsUtil)) | 153 , m_extensionsUtil(std::move(extensionsUtil)) |
| 147 , m_size(-1, -1) | 154 , m_size(-1, -1) |
| 148 , m_requestedAttributes(requestedAttributes) | |
| 149 , m_multisampleExtensionSupported(multisampleExtensionSupported) | |
| 150 , m_discardFramebufferSupported(discardFramebufferSupported) | 155 , m_discardFramebufferSupported(discardFramebufferSupported) |
| 156 , m_wantAlphaChannel(wantAlphaChannel) | |
| 151 , m_premultipliedAlpha(premultipliedAlpha) | 157 , m_premultipliedAlpha(premultipliedAlpha) |
| 158 , m_hasDepthBuffer(false) | |
| 159 , m_hasStencilBuffer(false) | |
| 160 , m_hasImplicitStencilBuffer(false) | |
| 152 , m_fbo(0) | 161 , m_fbo(0) |
| 153 , m_depthStencilBuffer(0) | 162 , m_depthStencilBuffer(0) |
| 154 , m_multisampleFBO(0) | 163 , m_multisampleFBO(0) |
| 155 , m_multisampleColorBuffer(0) | 164 , m_multisampleColorBuffer(0) |
| 156 , m_contentsChanged(true) | 165 , m_contentsChanged(true) |
| 157 , m_contentsChangeCommitted(false) | 166 , m_contentsChangeCommitted(false) |
| 158 , m_bufferClearNeeded(false) | 167 , m_bufferClearNeeded(false) |
| 159 , m_antiAliasingMode(None) | 168 , m_antiAliasingMode(None) |
| 160 , m_maxTextureSize(0) | 169 , m_maxTextureSize(0) |
| 161 , m_sampleCount(0) | 170 , m_sampleCount(0) |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 (*m_newMailboxCallback)(); | 270 (*m_newMailboxCallback)(); |
| 262 | 271 |
| 263 // Resolve the multisampled buffer into m_colorBuffer texture. | 272 // Resolve the multisampled buffer into m_colorBuffer texture. |
| 264 if (m_antiAliasingMode != None) | 273 if (m_antiAliasingMode != None) |
| 265 commit(); | 274 commit(); |
| 266 | 275 |
| 267 if (bitmap) { | 276 if (bitmap) { |
| 268 bitmap->setSize(size()); | 277 bitmap->setSize(size()); |
| 269 | 278 |
| 270 unsigned char* pixels = bitmap->pixels(); | 279 unsigned char* pixels = bitmap->pixels(); |
| 271 bool needPremultiply = m_actualAttributes.alpha && !m_premultipliedAlpha ; | 280 bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha; |
| 272 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing; | 281 WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversio n::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing; |
| 273 if (pixels) | 282 if (pixels) |
| 274 readBackFramebuffer(pixels, size().width(), size().height(), Readbac kSkia, op); | 283 readBackFramebuffer(pixels, size().width(), size().height(), Readbac kSkia, op); |
| 275 } | 284 } |
| 276 | 285 |
| 277 // We must restore the texture binding since creating new textures, | 286 // We must restore the texture binding since creating new textures, |
| 278 // consuming and producing mailboxes changes it. | 287 // consuming and producing mailboxes changes it. |
| 279 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, m_text ure2DBinding); | 288 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, m_text ure2DBinding); |
| 280 | 289 |
| 281 // First try to recycle an old buffer. | 290 // First try to recycle an old buffer. |
| 282 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); | 291 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); |
| 283 | 292 |
| 284 // No buffer available to recycle, create a new one. | 293 // No buffer available to recycle, create a new one. |
| 285 if (!frontColorBufferMailbox) { | 294 if (!frontColorBufferMailbox) |
| 286 frontColorBufferMailbox = createNewMailbox(createTextureAndAllocateMemor y(m_size)); | 295 frontColorBufferMailbox = createNewMailbox(createTextureAndAllocateMemor y(m_size)); |
| 287 } | |
| 288 | 296 |
| 289 if (m_preserveDrawingBuffer == Discard) { | 297 if (m_preserveDrawingBuffer == Discard) { |
| 290 std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer); | 298 std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer); |
| 291 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a | 299 // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a |
| 292 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. | 300 // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding. |
| 293 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore | 301 // If this stops being true at some point, we should track the current f ramebuffer binding in the DrawingBuffer and restore |
| 294 // it after attaching the new back buffer here. | 302 // it after attaching the new back buffer here. |
| 295 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 303 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 296 attachColorBufferToCurrentFBO(); | 304 attachColorBufferToCurrentFBO(); |
| 297 | 305 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 return parameters; | 368 return parameters; |
| 361 #else | 369 #else |
| 362 return defaultTextureParameters(); | 370 return defaultTextureParameters(); |
| 363 #endif | 371 #endif |
| 364 } | 372 } |
| 365 | 373 |
| 366 DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() | 374 DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() |
| 367 { | 375 { |
| 368 TextureParameters parameters; | 376 TextureParameters parameters; |
| 369 parameters.target = GL_TEXTURE_2D; | 377 parameters.target = GL_TEXTURE_2D; |
| 370 if (m_requestedAttributes.alpha) { | 378 if (m_wantAlphaChannel) { |
| 371 parameters.internalColorFormat = GL_RGBA; | 379 parameters.internalColorFormat = GL_RGBA; |
| 372 parameters.colorFormat = GL_RGBA; | 380 parameters.colorFormat = GL_RGBA; |
| 373 parameters.internalRenderbufferFormat = GL_RGBA8_OES; | 381 parameters.internalRenderbufferFormat = GL_RGBA8_OES; |
| 374 } else { | 382 } else { |
| 375 parameters.internalColorFormat = GL_RGB; | 383 parameters.internalColorFormat = GL_RGB; |
| 376 parameters.colorFormat = GL_RGB; | 384 parameters.colorFormat = GL_RGB; |
| 377 parameters.internalRenderbufferFormat = GL_RGB8_OES; | 385 parameters.internalRenderbufferFormat = GL_RGB8_OES; |
| 378 } | 386 } |
| 379 return parameters; | 387 return parameters; |
| 380 } | 388 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); | 450 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); |
| 443 | 451 |
| 444 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI d); | 452 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI d); |
| 445 m_textureMailboxes.remove(i); | 453 m_textureMailboxes.remove(i); |
| 446 return; | 454 return; |
| 447 } | 455 } |
| 448 } | 456 } |
| 449 ASSERT_NOT_REACHED(); | 457 ASSERT_NOT_REACHED(); |
| 450 } | 458 } |
| 451 | 459 |
| 452 bool DrawingBuffer::initialize(const IntSize& size) | 460 bool DrawingBuffer::initialize(const IntSize& size, bool wantDepthBuffer, bool w antStencilBuffer, bool multisampleExtensionSupported) |
| 453 { | 461 { |
| 454 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 462 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 455 // Need to try to restore the context again later. | 463 // Need to try to restore the context again later. |
| 456 return false; | 464 return false; |
| 457 } | 465 } |
| 458 | 466 |
| 459 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 467 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); |
| 460 | 468 |
| 461 int maxSampleCount = 0; | 469 int maxSampleCount = 0; |
| 462 m_antiAliasingMode = None; | 470 m_antiAliasingMode = None; |
| 463 if (m_requestedAttributes.antialias && m_multisampleExtensionSupported) { | 471 if (multisampleExtensionSupported) { |
| 464 m_gl->GetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount); | 472 m_gl->GetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount); |
| 465 m_antiAliasingMode = MSAAExplicitResolve; | 473 m_antiAliasingMode = MSAAExplicitResolve; |
| 466 if (m_extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_t exture")) { | 474 if (m_extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_t exture")) { |
| 467 m_antiAliasingMode = MSAAImplicitResolve; | 475 m_antiAliasingMode = MSAAImplicitResolve; |
| 468 } else if (m_extensionsUtil->supportsExtension("GL_CHROMIUM_screen_space _antialiasing")) { | 476 } else if (m_extensionsUtil->supportsExtension("GL_CHROMIUM_screen_space _antialiasing")) { |
| 469 m_antiAliasingMode = ScreenSpaceAntialiasing; | 477 m_antiAliasingMode = ScreenSpaceAntialiasing; |
| 470 } | 478 } |
| 471 } | 479 } |
| 472 m_sampleCount = std::min(4, maxSampleCount); | 480 m_sampleCount = std::min(4, maxSampleCount); |
| 473 | 481 |
| 474 m_gl->GenFramebuffers(1, &m_fbo); | 482 m_gl->GenFramebuffers(1, &m_fbo); |
| 475 | 483 |
| 476 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 484 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 477 createSecondaryBuffers(); | 485 createSecondaryBuffers(); |
| 478 // We first try to initialize everything with the requested attributes. | 486 if (!reset(size, wantDepthBuffer || wantStencilBuffer)) |
| 479 if (!reset(size)) | |
| 480 return false; | 487 return false; |
| 481 // If that succeeds, we then see what we actually got and update our actual attributes to reflect that. | 488 |
| 482 m_actualAttributes = m_requestedAttributes; | 489 if (m_depthStencilBuffer) { |
|
danakj
2016/03/31 22:13:02
Explanation of preserving old behaviour:
If reque
| |
| 483 if (m_requestedAttributes.alpha) { | 490 DCHECK(wantDepthBuffer || wantStencilBuffer); |
| 484 GLint alphaBits = 0; | 491 m_hasDepthBuffer = wantDepthBuffer; |
|
piman
2016/04/01 00:24:15
I'm not sure hasDepthBuffer/hasStencilBuffer are t
danakj
2016/04/01 00:40:50
That's an excellent point. I had to think this thr
danakj
2016/04/01 00:41:46
Oh, and if we use !!m_depthStencilBuffer there, th
| |
| 485 m_gl->GetIntegerv(GL_ALPHA_BITS, &alphaBits); | 492 m_hasStencilBuffer = wantStencilBuffer; |
| 486 m_actualAttributes.alpha = alphaBits > 0; | 493 m_hasImplicitStencilBuffer = !wantStencilBuffer; |
| 487 } | 494 } |
| 488 if (m_requestedAttributes.depth) { | |
| 489 GLint depthBits = 0; | |
| 490 m_gl->GetIntegerv(GL_DEPTH_BITS, &depthBits); | |
| 491 m_actualAttributes.depth = depthBits > 0; | |
| 492 } | |
| 493 if (m_requestedAttributes.stencil) { | |
| 494 GLint stencilBits = 0; | |
| 495 m_gl->GetIntegerv(GL_STENCIL_BITS, &stencilBits); | |
| 496 m_actualAttributes.stencil = stencilBits > 0; | |
| 497 } | |
| 498 m_actualAttributes.antialias = multisample(); | |
| 499 | 495 |
| 500 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 496 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 501 // It's possible that the drawing buffer allocation provokes a context l oss, so check again just in case. http://crbug.com/512302 | 497 // It's possible that the drawing buffer allocation provokes a context l oss, so check again just in case. http://crbug.com/512302 |
| 502 return false; | 498 return false; |
| 503 } | 499 } |
| 504 | 500 |
| 505 return true; | 501 return true; |
| 506 } | 502 } |
| 507 | 503 |
| 508 bool DrawingBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, gpu::gl es2::GLES2Interface* gl, GLuint texture, GLenum internalFormat, | 504 bool DrawingBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, gpu::gl es2::GLES2Interface* gl, GLuint texture, GLenum internalFormat, |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 538 m_gl->GenSyncTokenCHROMIUM(fenceSync, mailbox.syncToken); | 534 m_gl->GenSyncTokenCHROMIUM(fenceSync, mailbox.syncToken); |
| 539 mailbox.validSyncToken = true; | 535 mailbox.validSyncToken = true; |
| 540 } | 536 } |
| 541 | 537 |
| 542 if (mailbox.validSyncToken) | 538 if (mailbox.validSyncToken) |
| 543 gl->WaitSyncTokenCHROMIUM(mailbox.syncToken); | 539 gl->WaitSyncTokenCHROMIUM(mailbox.syncToken); |
| 544 GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.n ame); | 540 GLuint sourceTexture = gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.n ame); |
| 545 | 541 |
| 546 GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE; | 542 GLboolean unpackPremultiplyAlphaNeeded = GL_FALSE; |
| 547 GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE; | 543 GLboolean unpackUnpremultiplyAlphaNeeded = GL_FALSE; |
| 548 if (m_actualAttributes.alpha && m_premultipliedAlpha && !premultiplyAlpha) | 544 if (m_wantAlphaChannel && m_premultipliedAlpha && !premultiplyAlpha) |
| 549 unpackUnpremultiplyAlphaNeeded = GL_TRUE; | 545 unpackUnpremultiplyAlphaNeeded = GL_TRUE; |
| 550 else if (m_actualAttributes.alpha && !m_premultipliedAlpha && premultiplyAlp ha) | 546 else if (m_wantAlphaChannel && !m_premultipliedAlpha && premultiplyAlpha) |
| 551 unpackPremultiplyAlphaNeeded = GL_TRUE; | 547 unpackPremultiplyAlphaNeeded = GL_TRUE; |
| 552 | 548 |
| 553 gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, fl ipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded); | 549 gl->CopyTextureCHROMIUM(sourceTexture, texture, internalFormat, destType, fl ipY, unpackPremultiplyAlphaNeeded, unpackUnpremultiplyAlphaNeeded); |
| 554 | 550 |
| 555 gl->DeleteTextures(1, &sourceTexture); | 551 gl->DeleteTextures(1, &sourceTexture); |
| 556 | 552 |
| 557 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 553 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| 558 | 554 |
| 559 gl->Flush(); | 555 gl->Flush(); |
| 560 GLbyte syncToken[24]; | 556 GLbyte syncToken[24]; |
| 561 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken); | 557 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken); |
| 562 m_gl->WaitSyncTokenCHROMIUM(syncToken); | 558 m_gl->WaitSyncTokenCHROMIUM(syncToken); |
| 563 | 559 |
| 564 return true; | 560 return true; |
| 565 } | 561 } |
| 566 | 562 |
| 567 GLuint DrawingBuffer::framebuffer() const | 563 GLuint DrawingBuffer::framebuffer() const |
| 568 { | 564 { |
| 569 return m_fbo; | 565 return m_fbo; |
| 570 } | 566 } |
| 571 | 567 |
| 572 WebLayer* DrawingBuffer::platformLayer() | 568 WebLayer* DrawingBuffer::platformLayer() |
| 573 { | 569 { |
| 574 if (!m_layer) { | 570 if (!m_layer) { |
| 575 m_layer = adoptPtr(Platform::current()->compositorSupport()->createExter nalTextureLayer(this)); | 571 m_layer = adoptPtr(Platform::current()->compositorSupport()->createExter nalTextureLayer(this)); |
| 576 | 572 |
| 577 m_layer->setOpaque(!m_actualAttributes.alpha); | 573 m_layer->setOpaque(!m_wantAlphaChannel); |
| 578 m_layer->setBlendBackgroundColor(m_actualAttributes.alpha); | 574 m_layer->setBlendBackgroundColor(m_wantAlphaChannel); |
| 579 m_layer->setPremultipliedAlpha(m_premultipliedAlpha); | 575 m_layer->setPremultipliedAlpha(m_premultipliedAlpha); |
| 580 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 576 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); |
| 581 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 577 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
| 582 } | 578 } |
| 583 | 579 |
| 584 return m_layer->layer(); | 580 return m_layer->layer(); |
| 585 } | 581 } |
| 586 | 582 |
| 587 void DrawingBuffer::clearPlatformLayer() | 583 void DrawingBuffer::clearPlatformLayer() |
| 588 { | 584 { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 647 void DrawingBuffer::createSecondaryBuffers() | 643 void DrawingBuffer::createSecondaryBuffers() |
| 648 { | 644 { |
| 649 // create a multisample FBO | 645 // create a multisample FBO |
| 650 if (m_antiAliasingMode == MSAAExplicitResolve) { | 646 if (m_antiAliasingMode == MSAAExplicitResolve) { |
| 651 m_gl->GenFramebuffers(1, &m_multisampleFBO); | 647 m_gl->GenFramebuffers(1, &m_multisampleFBO); |
| 652 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 648 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 653 m_gl->GenRenderbuffers(1, &m_multisampleColorBuffer); | 649 m_gl->GenRenderbuffers(1, &m_multisampleColorBuffer); |
| 654 } | 650 } |
| 655 } | 651 } |
| 656 | 652 |
| 657 bool DrawingBuffer::resizeFramebuffer(const IntSize& size) | 653 bool DrawingBuffer::resizeFramebuffer(const IntSize& size, bool wantDepthOrStenc ilBuffer) |
| 658 { | 654 { |
| 659 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 655 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 660 if (m_antiAliasingMode != MSAAExplicitResolve) | 656 if (m_antiAliasingMode != MSAAExplicitResolve && wantDepthOrStencilBuffer) |
| 661 resizeDepthStencil(size); | 657 resizeDepthStencil(size); |
| 662 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | 658 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| 663 return false; | 659 return false; |
| 664 | 660 |
| 665 return true; | 661 return true; |
| 666 } | 662 } |
| 667 | 663 |
| 668 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) | 664 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size, bool wantD epthOrStencilBuffer) |
| 669 { | 665 { |
| 670 if (m_antiAliasingMode == MSAAExplicitResolve) { | 666 if (m_antiAliasingMode == MSAAExplicitResolve) { |
| 671 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 667 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 672 | 668 |
| 673 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); | 669 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); |
| 674 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo unt, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.hei ght()); | 670 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo unt, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.hei ght()); |
| 675 | 671 |
| 676 if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 672 if (m_gl->GetError() == GL_OUT_OF_MEMORY) |
| 677 return false; | 673 return false; |
| 678 | 674 |
| 679 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_R ENDERBUFFER, m_multisampleColorBuffer); | 675 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_R ENDERBUFFER, m_multisampleColorBuffer); |
| 680 resizeDepthStencil(size); | 676 if (wantDepthOrStencilBuffer) |
| 677 resizeDepthStencil(size); | |
| 681 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPL ETE) | 678 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPL ETE) |
| 682 return false; | 679 return false; |
| 683 } | 680 } |
| 684 | 681 |
| 685 return true; | 682 return true; |
| 686 } | 683 } |
| 687 | 684 |
| 688 void DrawingBuffer::resizeDepthStencil(const IntSize& size) | 685 void DrawingBuffer::resizeDepthStencil(const IntSize& size) |
| 689 { | 686 { |
| 690 if (!m_requestedAttributes.depth && !m_requestedAttributes.stencil) | |
| 691 return; | |
| 692 | |
| 693 if (!m_depthStencilBuffer) | 687 if (!m_depthStencilBuffer) |
| 694 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 688 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); |
| 695 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 689 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); |
| 696 if (m_antiAliasingMode == MSAAImplicitResolve) | 690 if (m_antiAliasingMode == MSAAImplicitResolve) |
| 697 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); | 691 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
| 698 else if (m_antiAliasingMode == MSAAExplicitResolve) | 692 else if (m_antiAliasingMode == MSAAExplicitResolve) |
| 699 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo unt, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); | 693 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo unt, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
| 700 else | 694 else |
| 701 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, size .width(), size.height()); | 695 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, size .width(), size.height()); |
| 702 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, G L_RENDERBUFFER, m_depthStencilBuffer); | 696 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, G L_RENDERBUFFER, m_depthStencilBuffer); |
| 703 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 697 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); |
| 704 } | 698 } |
| 705 | 699 |
| 706 | 700 |
| 707 | 701 |
| 708 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) | 702 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) |
| 709 { | 703 { |
| 710 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer. | 704 // We will clear the multisample FBO, but we also need to clear the non-mult isampled buffer. |
| 711 if (m_multisampleFBO) { | 705 if (m_multisampleFBO) { |
| 712 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 706 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 713 m_gl->Clear(GL_COLOR_BUFFER_BIT); | 707 m_gl->Clear(GL_COLOR_BUFFER_BIT); |
| 714 } | 708 } |
| 715 | 709 |
| 716 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); | 710 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| 717 m_gl->Clear(clearMask); | 711 m_gl->Clear(clearMask); |
| 718 } | 712 } |
| 719 | 713 |
| 720 bool DrawingBuffer::hasImplicitStencilBuffer() const | |
| 721 { | |
| 722 return m_depthStencilBuffer && m_requestedAttributes.depth && !m_requestedAt tributes.stencil; | |
| 723 } | |
| 724 | |
| 725 void DrawingBuffer::setSize(const IntSize& size) | 714 void DrawingBuffer::setSize(const IntSize& size) |
| 726 { | 715 { |
| 727 if (m_size == size) | 716 if (m_size == size) |
| 728 return; | 717 return; |
| 729 | 718 |
| 730 m_size = size; | 719 m_size = size; |
| 731 } | 720 } |
| 732 | 721 |
| 733 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, const IntSize& cur Size, int maxTextureSize) | 722 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, const IntSize& cur Size, int maxTextureSize) |
| 734 { | 723 { |
| 735 IntSize adjustedSize = desiredSize; | 724 IntSize adjustedSize = desiredSize; |
| 736 | 725 |
| 737 // Clamp if the desired size is greater than the maximum texture size for th e device. | 726 // Clamp if the desired size is greater than the maximum texture size for th e device. |
| 738 if (adjustedSize.height() > maxTextureSize) | 727 if (adjustedSize.height() > maxTextureSize) |
| 739 adjustedSize.setHeight(maxTextureSize); | 728 adjustedSize.setHeight(maxTextureSize); |
| 740 | 729 |
| 741 if (adjustedSize.width() > maxTextureSize) | 730 if (adjustedSize.width() > maxTextureSize) |
| 742 adjustedSize.setWidth(maxTextureSize); | 731 adjustedSize.setWidth(maxTextureSize); |
| 743 | 732 |
| 744 return adjustedSize; | 733 return adjustedSize; |
| 745 } | 734 } |
| 746 | 735 |
| 747 bool DrawingBuffer::reset(const IntSize& newSize) | 736 bool DrawingBuffer::reset(const IntSize& newSize, bool wantDepthOrStencilBuffer) |
| 748 { | 737 { |
| 749 ASSERT(!newSize.isEmpty()); | 738 ASSERT(!newSize.isEmpty()); |
| 750 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 739 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); |
| 751 if (adjustedSize.isEmpty()) | 740 if (adjustedSize.isEmpty()) |
| 752 return false; | 741 return false; |
| 753 | 742 |
| 754 if (adjustedSize != m_size) { | 743 if (adjustedSize != m_size) { |
| 755 do { | 744 do { |
| 756 if (m_colorBuffer.textureId) { | 745 if (m_colorBuffer.textureId) { |
| 757 resizeTextureMemory(&m_colorBuffer, adjustedSize); | 746 resizeTextureMemory(&m_colorBuffer, adjustedSize); |
| 758 } else { | 747 } else { |
| 759 m_colorBuffer = createTextureAndAllocateMemory(adjustedSize); | 748 m_colorBuffer = createTextureAndAllocateMemory(adjustedSize); |
| 760 } | 749 } |
| 761 | 750 |
| 762 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 751 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 763 attachColorBufferToCurrentFBO(); | 752 attachColorBufferToCurrentFBO(); |
| 764 | 753 |
| 765 // resize multisample FBO | 754 // resize multisample FBO |
| 766 if (!resizeMultisampleFramebuffer(adjustedSize) || !resizeFramebuffe r(adjustedSize)) { | 755 if (!resizeMultisampleFramebuffer(adjustedSize, wantDepthOrStencilBu ffer) |
| 756 || !resizeFramebuffer(adjustedSize, wantDepthOrStencilBuffer)) { | |
| 767 adjustedSize.scale(s_resourceAdjustedRatio); | 757 adjustedSize.scale(s_resourceAdjustedRatio); |
| 768 continue; | 758 continue; |
| 769 } | 759 } |
| 770 break; | 760 break; |
| 771 } while (!adjustedSize.isEmpty()); | 761 } while (!adjustedSize.isEmpty()); |
| 772 | 762 |
| 773 setSize(adjustedSize); | 763 setSize(adjustedSize); |
| 774 | 764 |
| 775 if (adjustedSize.isEmpty()) | 765 if (adjustedSize.isEmpty()) |
| 776 return false; | 766 return false; |
| 777 } | 767 } |
| 778 | 768 |
| 779 m_gl->Disable(GL_SCISSOR_TEST); | 769 m_gl->Disable(GL_SCISSOR_TEST); |
| 780 m_gl->ClearColor(0, 0, 0, 0); | 770 m_gl->ClearColor(0, 0, 0, 0); |
| 781 m_gl->ColorMask(true, true, true, true); | 771 m_gl->ColorMask(true, true, true, true); |
| 782 | 772 |
| 783 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 773 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; |
| 784 if (m_actualAttributes.depth) { | 774 if (m_hasDepthBuffer) { |
|
danakj
2016/03/31 22:13:02
I will point out while I'm here that it's a bit we
| |
| 785 m_gl->ClearDepthf(1.0f); | 775 m_gl->ClearDepthf(1.0f); |
| 786 clearMask |= GL_DEPTH_BUFFER_BIT; | 776 clearMask |= GL_DEPTH_BUFFER_BIT; |
| 787 m_gl->DepthMask(true); | 777 m_gl->DepthMask(true); |
| 788 } | 778 } |
| 789 if (m_actualAttributes.stencil) { | 779 if (m_hasStencilBuffer) { |
| 790 m_gl->ClearStencil(0); | 780 m_gl->ClearStencil(0); |
| 791 clearMask |= GL_STENCIL_BUFFER_BIT; | 781 clearMask |= GL_STENCIL_BUFFER_BIT; |
| 792 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 782 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); |
| 793 } | 783 } |
| 794 | 784 |
| 795 clearFramebuffers(clearMask); | 785 clearFramebuffers(clearMask); |
| 796 return true; | 786 return true; |
| 797 } | 787 } |
| 798 | 788 |
| 799 void DrawingBuffer::commit() | 789 void DrawingBuffer::commit() |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 960 m_gl->DestroyImageCHROMIUM(info->imageId); | 950 m_gl->DestroyImageCHROMIUM(info->imageId); |
| 961 info->imageId = 0; | 951 info->imageId = 0; |
| 962 } | 952 } |
| 963 } | 953 } |
| 964 | 954 |
| 965 DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory(const I ntSize& size) | 955 DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory(const I ntSize& size) |
| 966 { | 956 { |
| 967 // TODO(erikchen): Add support for a CHROMIUM_image back buffer whose | 957 // TODO(erikchen): Add support for a CHROMIUM_image back buffer whose |
| 968 // behavior mimics a texture with internal format GL_RGB. | 958 // behavior mimics a texture with internal format GL_RGB. |
| 969 // https://crbug.com/581777. | 959 // https://crbug.com/581777. |
| 970 if (!m_requestedAttributes.alpha) | 960 if (!m_wantAlphaChannel) |
| 971 return createDefaultTextureAndAllocateMemory(size); | 961 return createDefaultTextureAndAllocateMemory(size); |
| 972 | 962 |
| 973 if (!RuntimeEnabledFeatures::webGLImageChromiumEnabled()) | 963 if (!RuntimeEnabledFeatures::webGLImageChromiumEnabled()) |
| 974 return createDefaultTextureAndAllocateMemory(size); | 964 return createDefaultTextureAndAllocateMemory(size); |
| 975 | 965 |
| 976 // First, try to allocate a CHROMIUM_image. This always has the potential to | 966 // First, try to allocate a CHROMIUM_image. This always has the potential to |
| 977 // fail. | 967 // fail. |
| 978 TextureParameters parameters = chromiumImageTextureParameters(); | 968 TextureParameters parameters = chromiumImageTextureParameters(); |
| 979 GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(size.width(), size .height(), parameters.internalColorFormat, GC3D_SCANOUT_CHROMIUM); | 969 GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(size.width(), size .height(), parameters.internalColorFormat, GC3D_SCANOUT_CHROMIUM); |
| 980 if (!imageId) | 970 if (!imageId) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1032 | 1022 |
| 1033 if (m_antiAliasingMode == MSAAImplicitResolve) | 1023 if (m_antiAliasingMode == MSAAImplicitResolve) |
| 1034 m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACH MENT0, target, m_colorBuffer.textureId, 0, m_sampleCount); | 1024 m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACH MENT0, target, m_colorBuffer.textureId, 0, m_sampleCount); |
| 1035 else | 1025 else |
| 1036 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_colorBuffer.textureId, 0); | 1026 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_colorBuffer.textureId, 0); |
| 1037 | 1027 |
| 1038 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); | 1028 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); |
| 1039 } | 1029 } |
| 1040 | 1030 |
| 1041 } // namespace blink | 1031 } // namespace blink |
| OLD | NEW |