| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 extensionsUtil->ensureExtensionEnabled("GL_OES_rgb8_rgba8"); | 103 extensionsUtil->ensureExtensionEnabled("GL_OES_rgb8_rgba8"); |
| 104 if (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisamp
le")) | 104 if (extensionsUtil->supportsExtension("GL_CHROMIUM_framebuffer_multisamp
le")) |
| 105 extensionsUtil->ensureExtensionEnabled("GL_CHROMIUM_framebuffer_mult
isample"); | 105 extensionsUtil->ensureExtensionEnabled("GL_CHROMIUM_framebuffer_mult
isample"); |
| 106 else | 106 else |
| 107 extensionsUtil->ensureExtensionEnabled("GL_EXT_multisampled_render_t
o_texture"); | 107 extensionsUtil->ensureExtensionEnabled("GL_EXT_multisampled_render_t
o_texture"); |
| 108 } | 108 } |
| 109 bool discardFramebufferSupported = extensionsUtil->supportsExtension("GL_EXT
_discard_framebuffer"); | 109 bool discardFramebufferSupported = extensionsUtil->supportsExtension("GL_EXT
_discard_framebuffer"); |
| 110 if (discardFramebufferSupported) | 110 if (discardFramebufferSupported) |
| 111 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 111 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); |
| 112 | 112 |
| 113 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(c
ontextProvider), extensionsUtil.release(), discardFramebufferSupported, wantAlph
aChannel, premultipliedAlpha, preserve)); | 113 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(std::move(c
ontextProvider), extensionsUtil.release(), discardFramebufferSupported, wantAlph
aChannel, premultipliedAlpha, preserve, wantDepthBuffer, wantStencilBuffer)); |
| 114 if (!drawingBuffer->initialize(size, wantDepthBuffer, wantStencilBuffer, mul
tisampleSupported)) { | 114 if (!drawingBuffer->initialize(size, multisampleSupported)) { |
| 115 drawingBuffer->beginDestruction(); | 115 drawingBuffer->beginDestruction(); |
| 116 return PassRefPtr<DrawingBuffer>(); | 116 return PassRefPtr<DrawingBuffer>(); |
| 117 } | 117 } |
| 118 return drawingBuffer.release(); | 118 return drawingBuffer.release(); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void DrawingBuffer::forceNextDrawingBufferCreationToFail() | 121 void DrawingBuffer::forceNextDrawingBufferCreationToFail() |
| 122 { | 122 { |
| 123 shouldFailDrawingBufferCreationForTesting = true; | 123 shouldFailDrawingBufferCreationForTesting = true; |
| 124 } | 124 } |
| 125 | 125 |
| 126 DrawingBuffer::DrawingBuffer( | 126 DrawingBuffer::DrawingBuffer( |
| 127 PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, | 127 PassOwnPtr<WebGraphicsContext3DProvider> contextProvider, |
| 128 PassOwnPtr<Extensions3DUtil> extensionsUtil, | 128 PassOwnPtr<Extensions3DUtil> extensionsUtil, |
| 129 bool discardFramebufferSupported, | 129 bool discardFramebufferSupported, |
| 130 bool wantAlphaChannel, | 130 bool wantAlphaChannel, |
| 131 bool premultipliedAlpha, | 131 bool premultipliedAlpha, |
| 132 PreserveDrawingBuffer preserve) | 132 PreserveDrawingBuffer preserve, |
| 133 bool wantDepth, |
| 134 bool wantStencil) |
| 133 : m_preserveDrawingBuffer(preserve) | 135 : m_preserveDrawingBuffer(preserve) |
| 134 , m_scissorEnabled(false) | |
| 135 , m_texture2DBinding(0) | |
| 136 , m_drawFramebufferBinding(0) | |
| 137 , m_readFramebufferBinding(0) | |
| 138 , m_renderbufferBinding(0) | |
| 139 , m_activeTextureUnit(GL_TEXTURE0) | |
| 140 , m_contextProvider(std::move(contextProvider)) | 136 , m_contextProvider(std::move(contextProvider)) |
| 141 , m_gl(m_contextProvider->contextGL()) | 137 , m_gl(m_contextProvider->contextGL()) |
| 142 , m_extensionsUtil(std::move(extensionsUtil)) | 138 , m_extensionsUtil(std::move(extensionsUtil)) |
| 143 , m_size(-1, -1) | |
| 144 , m_discardFramebufferSupported(discardFramebufferSupported) | 139 , m_discardFramebufferSupported(discardFramebufferSupported) |
| 145 , m_wantAlphaChannel(wantAlphaChannel) | 140 , m_wantAlphaChannel(wantAlphaChannel) |
| 146 , m_premultipliedAlpha(premultipliedAlpha) | 141 , m_premultipliedAlpha(premultipliedAlpha) |
| 147 , m_hasImplicitStencilBuffer(false) | 142 , m_wantDepth(wantDepth) |
| 148 , m_fbo(0) | 143 , m_wantStencil(wantStencil) |
| 149 , m_depthStencilBuffer(0) | |
| 150 , m_multisampleFBO(0) | |
| 151 , m_intermediateFBO(0) | |
| 152 , m_intermediateRenderbuffer(0) | |
| 153 , m_multisampleColorBuffer(0) | |
| 154 , m_contentsChanged(true) | |
| 155 , m_contentsChangeCommitted(false) | |
| 156 , m_bufferClearNeeded(false) | |
| 157 , m_antiAliasingMode(None) | |
| 158 , m_maxTextureSize(0) | |
| 159 , m_sampleCount(0) | |
| 160 , m_packAlignment(4) | |
| 161 , m_destructionInProgress(false) | |
| 162 , m_isHidden(false) | |
| 163 , m_filterQuality(kLow_SkFilterQuality) | |
| 164 { | 144 { |
| 165 memset(m_colorMask, 0, 4 * sizeof(GLboolean)); | 145 memset(m_colorMask, 0, 4 * sizeof(GLboolean)); |
| 166 memset(m_clearColor, 0, 4 * sizeof(GLfloat)); | 146 memset(m_clearColor, 0, 4 * sizeof(GLfloat)); |
| 167 // Used by browser tests to detect the use of a DrawingBuffer. | 147 // Used by browser tests to detect the use of a DrawingBuffer. |
| 168 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", TRACE_EVENT_SCOPE_
GLOBAL); | 148 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", TRACE_EVENT_SCOPE_
GLOBAL); |
| 169 } | 149 } |
| 170 | 150 |
| 171 DrawingBuffer::~DrawingBuffer() | 151 DrawingBuffer::~DrawingBuffer() |
| 172 { | 152 { |
| 173 ASSERT(m_destructionInProgress); | 153 ASSERT(m_destructionInProgress); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 197 |
| 218 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) | 198 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) |
| 219 { | 199 { |
| 220 if (m_filterQuality != filterQuality) { | 200 if (m_filterQuality != filterQuality) { |
| 221 m_filterQuality = filterQuality; | 201 m_filterQuality = filterQuality; |
| 222 if (m_layer) | 202 if (m_layer) |
| 223 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); | 203 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); |
| 224 } | 204 } |
| 225 } | 205 } |
| 226 | 206 |
| 227 bool DrawingBuffer::requiresRGBEmulation() | 207 bool DrawingBuffer::requiresAlphaChannelToBePreserved() |
| 228 { | 208 { |
| 229 // When an explicit resolve is required, clients draw into a render buffer | 209 // When an explicit resolve is required, clients draw into a render buffer |
| 230 // which is never backed by an IOSurface. | 210 // which is never backed by an IOSurface. |
| 231 if (m_antiAliasingMode == MSAAExplicitResolve) | 211 if (m_antiAliasingMode == MSAAExplicitResolve) |
| 232 return false; | 212 return false; |
| 233 return !m_drawFramebufferBinding && !m_wantAlphaChannel && m_colorBuffer.ima
geId && contextProvider()->getCapabilities().chromium_image_rgb_emulation; | 213 return !m_drawFramebufferBinding && !m_wantAlphaChannel && m_colorBuffer.ima
geId && contextProvider()->getCapabilities().chromium_image_rgb_emulation; |
| 234 } | 214 } |
| 235 | 215 |
| 236 void DrawingBuffer::freeRecycledMailboxes() | 216 void DrawingBuffer::freeRecycledMailboxes() |
| 237 { | 217 { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 258 |
| 279 // First try to recycle an old buffer. | 259 // First try to recycle an old buffer. |
| 280 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); | 260 RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox(); |
| 281 | 261 |
| 282 // No buffer available to recycle, create a new one. | 262 // No buffer available to recycle, create a new one. |
| 283 if (!frontColorBufferMailbox) | 263 if (!frontColorBufferMailbox) |
| 284 frontColorBufferMailbox = createNewMailbox(createTextureAndAllocateMemor
y(m_size)); | 264 frontColorBufferMailbox = createNewMailbox(createTextureAndAllocateMemor
y(m_size)); |
| 285 | 265 |
| 286 if (m_preserveDrawingBuffer == Discard) { | 266 if (m_preserveDrawingBuffer == Discard) { |
| 287 std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer); | 267 std::swap(frontColorBufferMailbox->textureInfo, m_colorBuffer); |
| 288 // It appears safe to overwrite the context's framebuffer binding in the
Discard case since there will always be a | 268 attachColorBufferToReadFramebuffer(); |
| 289 // WebGLRenderingContext::clearIfComposited() call made before the next
draw call which restores the framebuffer binding. | |
| 290 // If this stops being true at some point, we should track the current f
ramebuffer binding in the DrawingBuffer and restore | |
| 291 // it after attaching the new back buffer here. | |
| 292 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | |
| 293 attachColorBufferToCurrentFBO(); | |
| 294 | 269 |
| 295 if (m_discardFramebufferSupported) { | 270 if (m_discardFramebufferSupported) { |
| 296 // Explicitly discard framebuffer to save GPU memory bandwidth for t
ile-based GPU arch. | 271 // Explicitly discard framebuffer to save GPU memory bandwidth for t
ile-based GPU arch. |
| 297 const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTAC
HMENT, GL_STENCIL_ATTACHMENT}; | 272 const GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTAC
HMENT, GL_STENCIL_ATTACHMENT }; |
| 298 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 273 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); |
| 299 } | 274 } |
| 300 } else { | 275 } else { |
| 301 m_gl->CopyTextureCHROMIUM(m_colorBuffer.textureId, frontColorBufferMailb
ox->textureInfo.textureId, frontColorBufferMailbox->textureInfo.parameters.inter
nalColorFormat, GL_UNSIGNED_BYTE, GL_FALSE, GL_FALSE, GL_FALSE); | 276 m_gl->CopyTextureCHROMIUM(m_colorBuffer.textureId, frontColorBufferMailb
ox->textureInfo.textureId, frontColorBufferMailbox->textureInfo.parameters.inter
nalColorFormat, GL_UNSIGNED_BYTE, GL_FALSE, GL_FALSE, GL_FALSE); |
| 302 } | 277 } |
| 303 | 278 |
| 304 restoreFramebufferBindings(); | 279 restoreFramebufferBindings(); |
| 305 m_contentsChanged = false; | 280 m_contentsChanged = false; |
| 306 | 281 |
| 307 m_gl->ProduceTextureDirectCHROMIUM(frontColorBufferMailbox->textureInfo.text
ureId, frontColorBufferMailbox->textureInfo.parameters.target, frontColorBufferM
ailbox->mailbox.name); | 282 m_gl->ProduceTextureDirectCHROMIUM(frontColorBufferMailbox->textureInfo.text
ureId, frontColorBufferMailbox->textureInfo.parameters.target, frontColorBufferM
ailbox->mailbox.name); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); | 430 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); |
| 456 | 431 |
| 457 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI
d); | 432 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureI
d); |
| 458 m_textureMailboxes.remove(i); | 433 m_textureMailboxes.remove(i); |
| 459 return; | 434 return; |
| 460 } | 435 } |
| 461 } | 436 } |
| 462 ASSERT_NOT_REACHED(); | 437 ASSERT_NOT_REACHED(); |
| 463 } | 438 } |
| 464 | 439 |
| 465 bool DrawingBuffer::initialize(const IntSize& size, bool wantDepthBuffer, bool w
antStencilBuffer, bool useMultisampling) | 440 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) |
| 466 { | 441 { |
| 467 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 442 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 468 // Need to try to restore the context again later. | 443 // Need to try to restore the context again later. |
| 469 return false; | 444 return false; |
| 470 } | 445 } |
| 471 | 446 |
| 472 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 447 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); |
| 473 | 448 |
| 474 int maxSampleCount = 0; | 449 int maxSampleCount = 0; |
| 475 m_antiAliasingMode = None; | 450 m_antiAliasingMode = None; |
| 476 if (useMultisampling) { | 451 if (useMultisampling) { |
| 477 m_gl->GetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount); | 452 m_gl->GetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount); |
| 478 m_antiAliasingMode = MSAAExplicitResolve; | 453 m_antiAliasingMode = MSAAExplicitResolve; |
| 479 if (m_extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_t
exture")) { | 454 if (m_extensionsUtil->supportsExtension("GL_EXT_multisampled_render_to_t
exture")) { |
| 480 m_antiAliasingMode = MSAAImplicitResolve; | 455 m_antiAliasingMode = MSAAImplicitResolve; |
| 481 } else if (m_extensionsUtil->supportsExtension("GL_CHROMIUM_screen_space
_antialiasing")) { | 456 } else if (m_extensionsUtil->supportsExtension("GL_CHROMIUM_screen_space
_antialiasing")) { |
| 482 m_antiAliasingMode = ScreenSpaceAntialiasing; | 457 m_antiAliasingMode = ScreenSpaceAntialiasing; |
| 483 } | 458 } |
| 484 } | 459 } |
| 485 m_sampleCount = std::min(4, maxSampleCount); | 460 m_sampleCount = std::min(4, maxSampleCount); |
| 486 | 461 |
| 487 m_gl->GenFramebuffers(1, &m_fbo); | 462 m_gl->GenFramebuffers(1, &m_fbo); |
| 488 | |
| 489 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 463 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 490 createSecondaryBuffers(); | 464 if (wantExplicitResolve()) { |
| 491 if (!reset(size, wantDepthBuffer || wantStencilBuffer)) | 465 m_gl->GenFramebuffers(1, &m_multisampleFBO); |
| 466 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 467 m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); |
| 468 } |
| 469 if (!reset(size)) |
| 492 return false; | 470 return false; |
| 493 | 471 |
| 494 if (m_depthStencilBuffer) { | 472 if (m_depthStencilBuffer) { |
| 495 DCHECK(wantDepthBuffer || wantStencilBuffer); | 473 DCHECK(wantDepthOrStencil()); |
| 496 m_hasImplicitStencilBuffer = !wantStencilBuffer; | 474 m_hasImplicitStencilBuffer = !m_wantStencil; |
| 497 } | 475 } |
| 498 | 476 |
| 499 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 477 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 500 // It's possible that the drawing buffer allocation provokes a context l
oss, so check again just in case. http://crbug.com/512302 | 478 // It's possible that the drawing buffer allocation provokes a context l
oss, so check again just in case. http://crbug.com/512302 |
| 501 return false; | 479 return false; |
| 502 } | 480 } |
| 503 | 481 |
| 504 return true; | 482 return true; |
| 505 } | 483 } |
| 506 | 484 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 | 578 |
| 601 while (!m_recycledMailboxQueue.isEmpty()) | 579 while (!m_recycledMailboxQueue.isEmpty()) |
| 602 deleteMailbox(m_recycledMailboxQueue.takeLast()); | 580 deleteMailbox(m_recycledMailboxQueue.takeLast()); |
| 603 | 581 |
| 604 if (m_multisampleFBO) | 582 if (m_multisampleFBO) |
| 605 m_gl->DeleteFramebuffers(1, &m_multisampleFBO); | 583 m_gl->DeleteFramebuffers(1, &m_multisampleFBO); |
| 606 | 584 |
| 607 if (m_fbo) | 585 if (m_fbo) |
| 608 m_gl->DeleteFramebuffers(1, &m_fbo); | 586 m_gl->DeleteFramebuffers(1, &m_fbo); |
| 609 | 587 |
| 610 if (m_multisampleColorBuffer) | 588 if (m_multisampleRenderbuffer) |
| 611 m_gl->DeleteRenderbuffers(1, &m_multisampleColorBuffer); | 589 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); |
| 612 | 590 |
| 613 if (m_intermediateFBO) | 591 if (m_intermediateFBO) |
| 614 m_gl->DeleteFramebuffers(1, &m_intermediateFBO); | 592 m_gl->DeleteFramebuffers(1, &m_intermediateFBO); |
| 615 | 593 |
| 616 if (m_intermediateRenderbuffer) | 594 if (m_intermediateRenderbuffer) |
| 617 m_gl->DeleteRenderbuffers(1, &m_intermediateRenderbuffer); | 595 m_gl->DeleteRenderbuffers(1, &m_intermediateRenderbuffer); |
| 618 | 596 |
| 619 if (m_depthStencilBuffer) | 597 if (m_depthStencilBuffer) |
| 620 m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer); | 598 m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer); |
| 621 | 599 |
| 622 if (m_colorBuffer.textureId) { | 600 if (m_colorBuffer.textureId) { |
| 623 deleteChromiumImageForTexture(&m_colorBuffer); | 601 deleteChromiumImageForTexture(&m_colorBuffer); |
| 624 m_gl->DeleteTextures(1, &m_colorBuffer.textureId); | 602 m_gl->DeleteTextures(1, &m_colorBuffer.textureId); |
| 625 } | 603 } |
| 626 | 604 |
| 627 setSize(IntSize()); | 605 setSize(IntSize()); |
| 628 | 606 |
| 629 m_colorBuffer = TextureInfo(); | 607 m_colorBuffer = TextureInfo(); |
| 630 m_frontColorBuffer = FrontBufferInfo(); | 608 m_frontColorBuffer = FrontBufferInfo(); |
| 631 m_multisampleColorBuffer = 0; | 609 m_multisampleRenderbuffer = 0; |
| 632 m_depthStencilBuffer = 0; | 610 m_depthStencilBuffer = 0; |
| 633 m_multisampleFBO = 0; | 611 m_multisampleFBO = 0; |
| 634 m_fbo = 0; | 612 m_fbo = 0; |
| 635 | 613 |
| 636 if (m_layer) | 614 if (m_layer) |
| 637 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 615 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 638 } | 616 } |
| 639 | 617 |
| 640 GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) | 618 GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) |
| 641 { | 619 { |
| 642 GLuint offscreenColorTexture; | 620 GLuint offscreenColorTexture; |
| 643 m_gl->GenTextures(1, &offscreenColorTexture); | 621 m_gl->GenTextures(1, &offscreenColorTexture); |
| 644 m_gl->BindTexture(parameters.target, offscreenColorTexture); | 622 m_gl->BindTexture(parameters.target, offscreenColorTexture); |
| 645 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 623 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 646 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 624 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 647 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 625 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 648 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 626 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 649 return offscreenColorTexture; | 627 return offscreenColorTexture; |
| 650 } | 628 } |
| 651 | 629 |
| 652 void DrawingBuffer::createSecondaryBuffers() | 630 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size) |
| 653 { | 631 { |
| 654 // create a multisample FBO | 632 DCHECK(wantExplicitResolve()); |
| 655 if (m_antiAliasingMode == MSAAExplicitResolve) { | 633 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 656 m_gl->GenFramebuffers(1, &m_multisampleFBO); | 634 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); |
| 657 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 635 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCount,
m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.height(
)); |
| 658 m_gl->GenRenderbuffers(1, &m_multisampleColorBuffer); | |
| 659 } | |
| 660 } | |
| 661 | 636 |
| 662 bool DrawingBuffer::resizeFramebuffer(const IntSize& size, bool wantDepthOrStenc
ilBuffer) | 637 if (m_gl->GetError() == GL_OUT_OF_MEMORY) |
| 663 { | |
| 664 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | |
| 665 if (m_antiAliasingMode != MSAAExplicitResolve && wantDepthOrStencilBuffer) | |
| 666 resizeDepthStencil(size); | |
| 667 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | |
| 668 return false; | 638 return false; |
| 669 | 639 |
| 670 return true; | 640 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDE
RBUFFER, m_multisampleRenderbuffer); |
| 671 } | |
| 672 | 641 |
| 673 bool DrawingBuffer::resizeMultisampleFramebuffer(const IntSize& size, bool wantD
epthOrStencilBuffer) | 642 if (m_intermediateFBO) { |
| 674 { | 643 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_intermediateFBO); |
| 675 if (m_antiAliasingMode == MSAAExplicitResolve) { | 644 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_intermediateRenderbuffer); |
| 676 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 645 m_gl->RenderbufferStorage(GL_RENDERBUFFER, m_colorBuffer.parameters.inte
rnalRenderbufferFormat, size.width(), size.height()); |
| 677 | |
| 678 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleColorBuffer); | |
| 679 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo
unt, m_colorBuffer.parameters.internalRenderbufferFormat, size.width(), size.hei
ght()); | |
| 680 | 646 |
| 681 if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 647 if (m_gl->GetError() == GL_OUT_OF_MEMORY) |
| 682 return false; | 648 return false; |
| 683 | 649 |
| 684 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_R
ENDERBUFFER, m_multisampleColorBuffer); | 650 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_R
ENDERBUFFER, m_intermediateRenderbuffer); |
| 685 if (wantDepthOrStencilBuffer) | |
| 686 resizeDepthStencil(size); | |
| 687 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPL
ETE) | 651 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPL
ETE) |
| 688 return false; | 652 return false; |
| 689 | 653 |
| 690 if (m_intermediateFBO) { | 654 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 691 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_intermediateFBO); | |
| 692 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_intermediateRenderbuffer); | |
| 693 m_gl->RenderbufferStorage(GL_RENDERBUFFER, m_colorBuffer.parameters.
internalRenderbufferFormat, size.width(), size.height()); | |
| 694 | |
| 695 if (m_gl->GetError() == GL_OUT_OF_MEMORY) | |
| 696 return false; | |
| 697 | |
| 698 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, m_intermediateRenderbuffer); | |
| 699 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_C
OMPLETE) | |
| 700 return false; | |
| 701 | |
| 702 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | |
| 703 } | |
| 704 } | 655 } |
| 705 | |
| 706 return true; | 656 return true; |
| 707 } | 657 } |
| 708 | 658 |
| 709 void DrawingBuffer::resizeDepthStencil(const IntSize& size) | 659 void DrawingBuffer::resizeDepthStencil(const IntSize& size) |
| 710 { | 660 { |
| 661 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO :
m_fbo); |
| 711 if (!m_depthStencilBuffer) | 662 if (!m_depthStencilBuffer) |
| 712 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 663 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); |
| 713 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 664 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); |
| 714 if (m_antiAliasingMode == MSAAImplicitResolve) | 665 if (m_antiAliasingMode == MSAAImplicitResolve) |
| 715 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount,
GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); | 666 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount,
GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
| 716 else if (m_antiAliasingMode == MSAAExplicitResolve) | 667 else if (m_antiAliasingMode == MSAAExplicitResolve) |
| 717 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo
unt, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); | 668 m_gl->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, m_sampleCo
unt, GL_DEPTH24_STENCIL8_OES, size.width(), size.height()); |
| 718 else | 669 else |
| 719 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, size
.width(), size.height()); | 670 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, size
.width(), size.height()); |
| 720 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we emulat
e it | 671 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we emulat
e it |
| 721 // at the command buffer level for WebGL contexts. | 672 // at the command buffer level for WebGL contexts. |
| 722 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, G
L_RENDERBUFFER, m_depthStencilBuffer); | 673 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, G
L_RENDERBUFFER, m_depthStencilBuffer); |
| 723 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 674 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); |
| 724 } | 675 } |
| 725 | 676 |
| 677 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) |
| 678 { |
| 679 // Resize or create m_colorBuffer. |
| 680 if (m_colorBuffer.textureId) { |
| 681 resizeTextureMemory(&m_colorBuffer, size); |
| 682 } else { |
| 683 m_colorBuffer = createTextureAndAllocateMemory(size); |
| 684 } |
| 726 | 685 |
| 686 attachColorBufferToReadFramebuffer(); |
| 687 |
| 688 if (wantExplicitResolve()) { |
| 689 if (!resizeMultisampleFramebuffer(size)) |
| 690 return false; |
| 691 } |
| 692 |
| 693 if (wantDepthOrStencil()) |
| 694 resizeDepthStencil(size); |
| 695 |
| 696 if (wantExplicitResolve()) { |
| 697 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 698 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPL
ETE) |
| 699 return false; |
| 700 } |
| 701 |
| 702 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 703 return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLE
TE; |
| 704 } |
| 727 | 705 |
| 728 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) | 706 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) |
| 729 { | 707 { |
| 730 // We will clear the multisample FBO, but we also need to clear the non-mult
isampled buffer. | 708 // We will clear the multisample FBO, but we also need to clear the non-mult
isampled buffer. |
| 731 if (m_multisampleFBO) { | 709 if (m_multisampleFBO) { |
| 732 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 710 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 733 m_gl->Clear(GL_COLOR_BUFFER_BIT); | 711 m_gl->Clear(GL_COLOR_BUFFER_BIT); |
| 734 } | 712 } |
| 735 | 713 |
| 736 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO :
m_fbo); | 714 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO ? m_multisampleFBO :
m_fbo); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 752 // Clamp if the desired size is greater than the maximum texture size for th
e device. | 730 // Clamp if the desired size is greater than the maximum texture size for th
e device. |
| 753 if (adjustedSize.height() > maxTextureSize) | 731 if (adjustedSize.height() > maxTextureSize) |
| 754 adjustedSize.setHeight(maxTextureSize); | 732 adjustedSize.setHeight(maxTextureSize); |
| 755 | 733 |
| 756 if (adjustedSize.width() > maxTextureSize) | 734 if (adjustedSize.width() > maxTextureSize) |
| 757 adjustedSize.setWidth(maxTextureSize); | 735 adjustedSize.setWidth(maxTextureSize); |
| 758 | 736 |
| 759 return adjustedSize; | 737 return adjustedSize; |
| 760 } | 738 } |
| 761 | 739 |
| 762 bool DrawingBuffer::reset(const IntSize& newSize, bool wantDepthOrStencilBuffer) | 740 bool DrawingBuffer::reset(const IntSize& newSize) |
| 763 { | 741 { |
| 764 ASSERT(!newSize.isEmpty()); | 742 ASSERT(!newSize.isEmpty()); |
| 765 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 743 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); |
| 766 if (adjustedSize.isEmpty()) | 744 if (adjustedSize.isEmpty()) |
| 767 return false; | 745 return false; |
| 768 | 746 |
| 769 if (adjustedSize != m_size) { | 747 if (adjustedSize != m_size) { |
| 770 do { | 748 do { |
| 771 if (m_colorBuffer.textureId) { | 749 if (!resizeDefaultFramebuffer(adjustedSize)) { |
| 772 resizeTextureMemory(&m_colorBuffer, adjustedSize); | |
| 773 } else { | |
| 774 m_colorBuffer = createTextureAndAllocateMemory(adjustedSize); | |
| 775 } | |
| 776 | |
| 777 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | |
| 778 attachColorBufferToCurrentFBO(); | |
| 779 | |
| 780 // resize multisample FBO | |
| 781 if (!resizeMultisampleFramebuffer(adjustedSize, wantDepthOrStencilBu
ffer) | |
| 782 || !resizeFramebuffer(adjustedSize, wantDepthOrStencilBuffer)) { | |
| 783 adjustedSize.scale(s_resourceAdjustedRatio); | 750 adjustedSize.scale(s_resourceAdjustedRatio); |
| 784 continue; | 751 continue; |
| 785 } | 752 } |
| 786 break; | 753 break; |
| 787 } while (!adjustedSize.isEmpty()); | 754 } while (!adjustedSize.isEmpty()); |
| 788 | 755 |
| 789 setSize(adjustedSize); | 756 setSize(adjustedSize); |
| 790 | 757 |
| 791 if (adjustedSize.isEmpty()) | 758 if (adjustedSize.isEmpty()) |
| 792 return false; | 759 return false; |
| 793 } | 760 } |
| 794 | 761 |
| 795 m_gl->Disable(GL_SCISSOR_TEST); | 762 m_gl->Disable(GL_SCISSOR_TEST); |
| 796 m_gl->ClearColor(0, 0, 0, 0); | 763 m_gl->ClearColor(0, 0, 0, 0); |
| 797 m_gl->ColorMask(true, true, true, !requiresRGBEmulation()); | 764 m_gl->ColorMask(true, true, true, !requiresAlphaChannelToBePreserved()); |
| 798 | 765 |
| 799 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 766 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; |
| 800 if (!!m_depthStencilBuffer) { | 767 if (!!m_depthStencilBuffer) { |
| 801 m_gl->ClearDepthf(1.0f); | 768 m_gl->ClearDepthf(1.0f); |
| 802 clearMask |= GL_DEPTH_BUFFER_BIT; | 769 clearMask |= GL_DEPTH_BUFFER_BIT; |
| 803 m_gl->DepthMask(true); | 770 m_gl->DepthMask(true); |
| 804 } | 771 } |
| 805 if (!!m_depthStencilBuffer) { | 772 if (!!m_depthStencilBuffer) { |
| 806 m_gl->ClearStencil(0); | 773 m_gl->ClearStencil(0); |
| 807 clearMask |= GL_STENCIL_BUFFER_BIT; | 774 clearMask |= GL_STENCIL_BUFFER_BIT; |
| 808 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 775 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); |
| 809 } | 776 } |
| 810 | 777 |
| 811 clearFramebuffers(clearMask); | 778 clearFramebuffers(clearMask); |
| 812 return true; | 779 return true; |
| 813 } | 780 } |
| 814 | 781 |
| 815 void DrawingBuffer::commit() | 782 void DrawingBuffer::commit() |
| 816 { | 783 { |
| 817 if (m_multisampleFBO && !m_contentsChangeCommitted) { | 784 if (wantExplicitResolve() && !m_contentsChangeCommitted) { |
| 818 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 785 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); |
| 819 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 786 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); |
| 820 | 787 |
| 821 if (m_scissorEnabled) | 788 if (m_scissorEnabled) |
| 822 m_gl->Disable(GL_SCISSOR_TEST); | 789 m_gl->Disable(GL_SCISSOR_TEST); |
| 823 | 790 |
| 824 int width = m_size.width(); | 791 int width = m_size.width(); |
| 825 int height = m_size.height(); | 792 int height = m_size.height(); |
| 826 // Use NEAREST, because there is no scale performed during the blit. | 793 // Use NEAREST, because there is no scale performed during the blit. |
| 827 GLuint filter = GL_NEAREST; | 794 GLuint filter = GL_NEAREST; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 } | 857 } |
| 891 } | 858 } |
| 892 | 859 |
| 893 bool DrawingBuffer::multisample() const | 860 bool DrawingBuffer::multisample() const |
| 894 { | 861 { |
| 895 return m_antiAliasingMode != None; | 862 return m_antiAliasingMode != None; |
| 896 } | 863 } |
| 897 | 864 |
| 898 void DrawingBuffer::bind(GLenum target) | 865 void DrawingBuffer::bind(GLenum target) |
| 899 { | 866 { |
| 900 if (target != GL_READ_FRAMEBUFFER) | 867 m_gl->BindFramebuffer(target, wantExplicitResolve() ? m_multisampleFBO : m_f
bo); |
| 901 m_gl->BindFramebuffer(target, m_multisampleFBO ? m_multisampleFBO : m_fb
o); | |
| 902 else | |
| 903 m_gl->BindFramebuffer(target, m_fbo); | |
| 904 } | 868 } |
| 905 | 869 |
| 906 void DrawingBuffer::setPackAlignment(GLint param) | 870 void DrawingBuffer::setPackAlignment(GLint param) |
| 907 { | 871 { |
| 908 m_packAlignment = param; | 872 m_packAlignment = param; |
| 909 } | 873 } |
| 910 | 874 |
| 911 bool DrawingBuffer::paintRenderingResultsToImageData(int& width, int& height, So
urceDrawingBuffer sourceBuffer, WTF::ArrayBufferContents& contents) | 875 bool DrawingBuffer::paintRenderingResultsToImageData(int& width, int& height, So
urceDrawingBuffer sourceBuffer, WTF::ArrayBufferContents& contents) |
| 912 { | 876 { |
| 913 ASSERT(!m_premultipliedAlpha); | 877 ASSERT(!m_premultipliedAlpha); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 // If the desired texture target is different, there's no way to fall ba
ck | 1043 // If the desired texture target is different, there's no way to fall ba
ck |
| 1080 // to a non CHROMIUM_image texture. | 1044 // to a non CHROMIUM_image texture. |
| 1081 if (chromiumImageTextureParameters().target != defaultTextureParameters(
).target) | 1045 if (chromiumImageTextureParameters().target != defaultTextureParameters(
).target) |
| 1082 return; | 1046 return; |
| 1083 } | 1047 } |
| 1084 | 1048 |
| 1085 m_gl->BindTexture(info->parameters.target, info->textureId); | 1049 m_gl->BindTexture(info->parameters.target, info->textureId); |
| 1086 texImage2DResourceSafe(info->parameters.target, 0, info->parameters.creation
InternalColorFormat, size.width(), size.height(), 0, info->parameters.colorForma
t, GL_UNSIGNED_BYTE); | 1050 texImage2DResourceSafe(info->parameters.target, 0, info->parameters.creation
InternalColorFormat, size.width(), size.height(), 0, info->parameters.colorForma
t, GL_UNSIGNED_BYTE); |
| 1087 } | 1051 } |
| 1088 | 1052 |
| 1089 void DrawingBuffer::attachColorBufferToCurrentFBO() | 1053 void DrawingBuffer::attachColorBufferToReadFramebuffer() |
| 1090 { | 1054 { |
| 1055 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 1056 |
| 1091 GLenum target = m_colorBuffer.parameters.target; | 1057 GLenum target = m_colorBuffer.parameters.target; |
| 1058 GLenum id = m_colorBuffer.textureId; |
| 1092 | 1059 |
| 1093 m_gl->BindTexture(target, m_colorBuffer.textureId); | 1060 m_gl->BindTexture(target, id); |
| 1094 | 1061 |
| 1095 if (m_antiAliasingMode == MSAAImplicitResolve) | 1062 if (m_antiAliasingMode == MSAAImplicitResolve) |
| 1096 m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACH
MENT0, target, m_colorBuffer.textureId, 0, m_sampleCount); | 1063 m_gl->FramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACH
MENT0, target, id, 0, m_sampleCount); |
| 1097 else | 1064 else |
| 1098 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
m_colorBuffer.textureId, 0); | 1065 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
id, 0); |
| 1099 | 1066 |
| 1067 restoreTextureBindings(); |
| 1068 restoreFramebufferBindings(); |
| 1069 } |
| 1070 |
| 1071 bool DrawingBuffer::wantExplicitResolve() |
| 1072 { |
| 1073 return m_antiAliasingMode == MSAAExplicitResolve; |
| 1074 } |
| 1075 |
| 1076 bool DrawingBuffer::wantDepthOrStencil() |
| 1077 { |
| 1078 return m_wantDepth || m_wantStencil; |
| 1079 } |
| 1080 |
| 1081 void DrawingBuffer::restoreTextureBindings() |
| 1082 { |
| 1083 // This class potentially modifies the bindings for GL_TEXTURE_2D and |
| 1084 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since |
| 1085 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. |
| 1100 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); | 1086 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); |
| 1101 } | 1087 } |
| 1102 | 1088 |
| 1103 } // namespace blink | 1089 } // namespace blink |
| OLD | NEW |