 Chromium Code Reviews
 Chromium Code Reviews Issue 2397713005:
  DrawingBuffer clean-up: Aesthetic changes  (Closed)
    
  
    Issue 2397713005:
  DrawingBuffer clean-up: Aesthetic changes  (Closed) 
  | Index: third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp | 
| diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp | 
| index 4b4b551a288c47ccb899e690d19733edde1cdcf5..665dc8c3a95d4f58a65c8f157e6fb60ec94018c2 100644 | 
| --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp | 
| +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp | 
| @@ -217,7 +217,7 @@ void DrawingBuffer::setIsHidden(bool hidden) { | 
| return; | 
| m_isHidden = hidden; | 
| if (m_isHidden) { | 
| - m_recycledMailboxQueue.clear(); | 
| + m_recycledColorBufferQueue.clear(); | 
| m_frontColorBuffer = nullptr; | 
| } | 
| } | 
| @@ -304,32 +304,47 @@ bool DrawingBuffer::prepareTextureMailboxInternal( | 
| commit(); | 
| if (m_softwareRendering && !forceGpuResult) { | 
| - std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); | 
| - if (!bitmap) | 
| - return false; | 
| + return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); | 
| + } else { | 
| + return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); | 
| + } | 
| +} | 
| + | 
| +bool DrawingBuffer::finishPrepareTextureMailboxSoftware( | 
| + cc::TextureMailbox* outMailbox, | 
| + std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
| + std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); | 
| + if (!bitmap) | 
| + return false; | 
| + | 
| + // Read the framebuffer into |bitmap|. | 
| + { | 
| unsigned char* pixels = bitmap->pixels(); | 
| DCHECK(pixels); | 
| - | 
| bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha; | 
| WebGLImageConversion::AlphaOp op = | 
| needPremultiply ? WebGLImageConversion::AlphaDoPremultiply | 
| : WebGLImageConversion::AlphaDoNothing; | 
| readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia, | 
| op); | 
| + } | 
| - *outMailbox = cc::TextureMailbox(bitmap.get(), m_size); | 
| + *outMailbox = cc::TextureMailbox(bitmap.get(), m_size); | 
| - // This holds a ref on the DrawingBuffer that will keep it alive until the | 
| - // mailbox is released (and while the release callback is running). It also | 
| - // owns the SharedBitmap. | 
| - auto func = WTF::bind(&DrawingBuffer::softwareMailboxReleased, | 
| - RefPtr<DrawingBuffer>(this), | 
| - WTF::passed(std::move(bitmap)), m_size); | 
| - *outReleaseCallback = cc::SingleReleaseCallback::Create( | 
| - convertToBaseCallback(std::move(func))); | 
| - return true; | 
| - } | 
| + // This holds a ref on the DrawingBuffer that will keep it alive until the | 
| + // mailbox is released (and while the release callback is running). It also | 
| + // owns the SharedBitmap. | 
| + auto func = WTF::bind(&DrawingBuffer::mailboxReleasedSoftware, | 
| + RefPtr<DrawingBuffer>(this), | 
| + WTF::passed(std::move(bitmap)), m_size); | 
| + *outReleaseCallback = | 
| + cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); | 
| + return true; | 
| +} | 
| +bool DrawingBuffer::finishPrepareTextureMailboxGpu( | 
| + cc::TextureMailbox* outMailbox, | 
| + std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
| if (m_webGLVersion > WebGL1) { | 
| m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 
| } | 
| @@ -339,69 +354,77 @@ bool DrawingBuffer::prepareTextureMailboxInternal( | 
| ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, | 
| m_texture2DBinding); | 
| - // First try to recycle an old buffer. | 
| - RefPtr<ColorBuffer> colorBufferForMailbox = takeRecycledMailbox(); | 
| - | 
| - // No buffer available to recycle, create a new one. | 
| - if (!colorBufferForMailbox) | 
| - colorBufferForMailbox = createTextureAndAllocateMemory(m_size); | 
| - | 
| + // Specify the buffer that we will put in the mailbox. | 
| + RefPtr<ColorBuffer> colorBufferForMailbox; | 
| if (m_preserveDrawingBuffer == Discard) { | 
| - std::swap(colorBufferForMailbox, m_backColorBuffer); | 
| + // If we can discard the backbuffer, send the old backbuffer directly | 
| + // into the mailbox, and allocate (or recycle) a new backbuffer. | 
| + colorBufferForMailbox = m_backColorBuffer; | 
| + m_backColorBuffer = createOrRecycleColorBuffer(); | 
| attachColorBufferToReadFramebuffer(); | 
| + // Explicitly specify that m_fbo (which is now bound to the just-allocated | 
| + // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for | 
| + // tile-based GPU architectures. | 
| if (m_discardFramebufferSupported) { | 
| - // Explicitly discard the framebuffer to save GPU memory bandwidth for | 
| - // tile-based GPU arch. | 
| const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 
| GL_STENCIL_ATTACHMENT}; | 
| m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 
| } | 
| } else { | 
| + // If we can't discard the backbuffer, create (or recycle) a buffer to put | 
| + // in the mailbox, and copy backbuffer's contents there. | 
| + colorBufferForMailbox = createOrRecycleColorBuffer(); | 
| m_gl->CopySubTextureCHROMIUM( | 
| m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, | 
| 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 
| } | 
| - restoreFramebufferBindings(); | 
| - restorePixelUnpackBufferBindings(); | 
| - m_contentsChanged = false; | 
| - | 
| - m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId, | 
| - colorBufferForMailbox->parameters.target, | 
| - colorBufferForMailbox->mailbox.name); | 
| - const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); | 
| + // Put colorBufferForMailbox into its mailbox, and populate its | 
| + // produceSyncToken with that point. | 
| + { | 
| + m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId, | 
| + colorBufferForMailbox->parameters.target, | 
| + colorBufferForMailbox->mailbox.name); | 
| + const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); | 
| #if OS(MACOSX) | 
| - m_gl->DescheduleUntilFinishedCHROMIUM(); | 
| + m_gl->DescheduleUntilFinishedCHROMIUM(); | 
| #endif | 
| - m_gl->Flush(); | 
| - gpu::SyncToken syncToken; | 
| - m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); | 
| + m_gl->Flush(); | 
| + m_gl->GenSyncTokenCHROMIUM( | 
| + fenceSync, colorBufferForMailbox->produceSyncToken.GetData()); | 
| + } | 
| - bool isOverlayCandidate = colorBufferForMailbox->imageId != 0; | 
| - bool secureOutputOnly = false; | 
| - *outMailbox = cc::TextureMailbox(colorBufferForMailbox->mailbox, syncToken, | 
| - colorBufferForMailbox->parameters.target, | 
| - gfx::Size(m_size.width(), m_size.height()), | 
| - isOverlayCandidate, secureOutputOnly); | 
| + // Populate the output mailbox and callback. | 
| + { | 
| + bool isOverlayCandidate = colorBufferForMailbox->imageId != 0; | 
| + bool secureOutputOnly = false; | 
| + *outMailbox = cc::TextureMailbox( | 
| + colorBufferForMailbox->mailbox, colorBufferForMailbox->produceSyncToken, | 
| + colorBufferForMailbox->parameters.target, gfx::Size(m_size), | 
| + isOverlayCandidate, secureOutputOnly); | 
| - // This holds a ref on the DrawingBuffer that will keep it alive until the | 
| - // mailbox is released (and while the release callback is running). | 
| - auto func = WTF::bind(&DrawingBuffer::gpuMailboxReleased, | 
| - RefPtr<DrawingBuffer>(this), colorBufferForMailbox); | 
| - *outReleaseCallback = | 
| - cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); | 
| + // This holds a ref on the DrawingBuffer that will keep it alive until the | 
| + // mailbox is released (and while the release callback is running). | 
| + auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, | 
| + RefPtr<DrawingBuffer>(this), colorBufferForMailbox); | 
| + *outReleaseCallback = cc::SingleReleaseCallback::Create( | 
| + convertToBaseCallback(std::move(func))); | 
| + } | 
| - // Point |m_frontColorBuffer| to the buffer that we are presenting, and | 
| - // update its sync token. | 
| - colorBufferForMailbox->produceSyncToken = syncToken; | 
| + // Point |m_frontColorBuffer| to the buffer that we are now presenting. | 
| m_frontColorBuffer = colorBufferForMailbox; | 
| + | 
| + // Restore any state that we may have dirtied, and update dirty bits. | 
| + restoreFramebufferBindings(); | 
| + restorePixelUnpackBufferBindings(); | 
| + m_contentsChanged = false; | 
| setBufferClearNeeded(true); | 
| return true; | 
| } | 
| -void DrawingBuffer::gpuMailboxReleased(RefPtr<ColorBuffer> colorBuffer, | 
| +void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, | 
| const gpu::SyncToken& syncToken, | 
| bool lostResource) { | 
| // Update the SyncToken to ensure that we will wait for it even if we | 
| @@ -419,13 +442,13 @@ void DrawingBuffer::gpuMailboxReleased(RefPtr<ColorBuffer> colorBuffer, | 
| size_t cacheLimit = 1; | 
| if (shouldUseChromiumImage()) | 
| cacheLimit = 4; | 
| - while (m_recycledMailboxQueue.size() >= cacheLimit) | 
| - m_recycledMailboxQueue.takeLast(); | 
| + while (m_recycledColorBufferQueue.size() >= cacheLimit) | 
| + m_recycledColorBufferQueue.takeLast(); | 
| - m_recycledMailboxQueue.prepend(colorBuffer); | 
| + m_recycledColorBufferQueue.prepend(colorBuffer); | 
| } | 
| -void DrawingBuffer::softwareMailboxReleased( | 
| +void DrawingBuffer::mailboxReleasedSoftware( | 
| std::unique_ptr<cc::SharedBitmap> bitmap, | 
| const IntSize& size, | 
| const gpu::SyncToken& syncToken, | 
| @@ -511,12 +534,12 @@ PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { | 
| std::move(skImage), skImageMailbox, skImageSyncToken); | 
| } | 
| -DrawingBuffer::TextureParameters | 
| -DrawingBuffer::chromiumImageTextureParameters() { | 
| +DrawingBuffer::ColorBufferParameters | 
| +DrawingBuffer::gpuMemoryBufferColorBufferParameters() { | 
| #if OS(MACOSX) | 
| // A CHROMIUM_image backed texture requires a specialized set of parameters | 
| // on OSX. | 
| - TextureParameters parameters; | 
| + ColorBufferParameters parameters; | 
| parameters.target = GC3D_TEXTURE_RECTANGLE_ARB; | 
| if (m_wantAlphaChannel) { | 
| @@ -538,12 +561,13 @@ DrawingBuffer::chromiumImageTextureParameters() { | 
| parameters.colorFormat = 0; | 
| return parameters; | 
| #else | 
| - return defaultTextureParameters(); | 
| + return textureColorBufferParameters(); | 
| #endif | 
| } | 
| -DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() { | 
| - TextureParameters parameters; | 
| +DrawingBuffer::ColorBufferParameters | 
| +DrawingBuffer::textureColorBufferParameters() { | 
| + ColorBufferParameters parameters; | 
| parameters.target = GL_TEXTURE_2D; | 
| if (m_wantAlphaChannel) { | 
| parameters.internalColorFormat = GL_RGBA; | 
| @@ -565,21 +589,28 @@ DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() { | 
| return parameters; | 
| } | 
| -PassRefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::takeRecycledMailbox() { | 
| - if (m_recycledMailboxQueue.isEmpty()) | 
| - return nullptr; | 
| - | 
| - RefPtr<ColorBuffer> recycled = m_recycledMailboxQueue.takeLast(); | 
| - DCHECK(recycled->size == m_size); | 
| - if (recycled->receiveSyncToken.HasData()) | 
| - m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData()); | 
| - return recycled; | 
| +PassRefPtr<DrawingBuffer::ColorBuffer> | 
| +DrawingBuffer::createOrRecycleColorBuffer() { | 
| + if (!m_recycledColorBufferQueue.isEmpty()) { | 
| + RefPtr<ColorBuffer> recycled = m_recycledColorBufferQueue.takeLast(); | 
| + if (recycled->receiveSyncToken.HasData()) | 
| + m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData()); | 
| + DCHECK(recycled->size == m_size); | 
| + return recycled; | 
| + } | 
| + return createColorBuffer(m_size); | 
| } | 
| DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer, | 
| - const TextureParameters& parameters, | 
| - const IntSize& size) | 
| - : drawingBuffer(drawingBuffer), parameters(parameters), size(size) { | 
| + const ColorBufferParameters& parameters, | 
| + const IntSize& size, | 
| + GLuint textureId, | 
| + GLuint imageId) | 
| + : drawingBuffer(drawingBuffer), | 
| + parameters(parameters), | 
| + size(size), | 
| + textureId(textureId), | 
| + imageId(imageId) { | 
| drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); | 
| } | 
| @@ -751,7 +782,7 @@ void DrawingBuffer::beginDestruction() { | 
| m_destructionInProgress = true; | 
| clearPlatformLayer(); | 
| - m_recycledMailboxQueue.clear(); | 
| + m_recycledColorBufferQueue.clear(); | 
| if (m_multisampleFBO) | 
| m_gl->DeleteFramebuffers(1, &m_multisampleFBO); | 
| @@ -778,20 +809,9 @@ void DrawingBuffer::beginDestruction() { | 
| GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 
| } | 
| -GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) { | 
| - GLuint offscreenColorTexture; | 
| - m_gl->GenTextures(1, &offscreenColorTexture); | 
| - m_gl->BindTexture(parameters.target, offscreenColorTexture); | 
| - m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
| - m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
| - m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
| - m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
| - return offscreenColorTexture; | 
| -} | 
| - | 
| bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { | 
| // Recreate m_backColorBuffer. | 
| - m_backColorBuffer = createTextureAndAllocateMemory(size); | 
| + m_backColorBuffer = createColorBuffer(size); | 
| attachColorBufferToReadFramebuffer(); | 
| @@ -893,7 +913,7 @@ bool DrawingBuffer::reset(const IntSize& newSize) { | 
| m_size = adjustedSize; | 
| // Free all mailboxes, because they are now of the wrong size. Only the | 
| // first call in this loop has any effect. | 
| - m_recycledMailboxQueue.clear(); | 
| + m_recycledColorBufferQueue.clear(); | 
| m_recycledBitmaps.clear(); | 
| if (adjustedSize.isEmpty()) | 
| @@ -1090,97 +1110,90 @@ void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, | 
| void DrawingBuffer::flipVertically(uint8_t* framebuffer, | 
| int width, | 
| int height) { | 
| - m_scanline.resize(width * 4); | 
| - uint8_t* scanline = &m_scanline[0]; | 
| + std::vector<uint8_t> scanline(width * 4); | 
| unsigned rowBytes = width * 4; | 
| unsigned count = height / 2; | 
| for (unsigned i = 0; i < count; i++) { | 
| uint8_t* rowA = framebuffer + i * rowBytes; | 
| uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; | 
| - memcpy(scanline, rowB, rowBytes); | 
| + memcpy(scanline.data(), rowB, rowBytes); | 
| memcpy(rowB, rowA, rowBytes); | 
| - memcpy(rowA, scanline, rowBytes); | 
| + memcpy(rowA, scanline.data(), rowBytes); | 
| } | 
| } | 
| -void DrawingBuffer::allocateConditionallyImmutableTexture(GLenum target, | 
| - GLenum internalformat, | 
| - GLsizei width, | 
| - GLsizei height, | 
| - GLint border, | 
| - GLenum format, | 
| - GLenum type) { | 
| - if (m_storageTextureSupported) { | 
| - GLenum internalStorageFormat = GL_NONE; | 
| - if (internalformat == GL_RGB) { | 
| - internalStorageFormat = GL_RGB8; | 
| - } else if (internalformat == GL_RGBA) { | 
| - internalStorageFormat = GL_RGBA8; | 
| - } else { | 
| - NOTREACHED(); | 
| - } | 
| - m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, width, | 
| - height); | 
| - return; | 
| +RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( | 
| + const IntSize& size) { | 
| + // Select the Parameters for the texture object. Allocate the backing | 
| + // GpuMemoryBuffer and GLImage, if one is going to be used. | 
| + ColorBufferParameters parameters; | 
| + GLuint imageId = 0; | 
| + if (shouldUseChromiumImage()) { | 
| + parameters = gpuMemoryBufferColorBufferParameters(); | 
| + imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( | 
| + size.width(), size.height(), parameters.creationInternalColorFormat, | 
| + GC3D_SCANOUT_CHROMIUM); | 
| + } else { | 
| + parameters = textureColorBufferParameters(); | 
| } | 
| - m_gl->TexImage2D(target, 0, internalformat, width, height, border, format, | 
| - type, 0); | 
| -} | 
| -void DrawingBuffer::clearChromiumImageAlpha(const ColorBuffer& info) { | 
| - if (m_wantAlphaChannel) | 
| - return; | 
| - if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 
| - return; | 
| - | 
| - GLuint fbo = 0; | 
| - m_gl->GenFramebuffers(1, &fbo); | 
| - m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 
| - m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| - info.parameters.target, info.textureId, 0); | 
| - m_gl->ClearColor(0, 0, 0, 1); | 
| - m_gl->ColorMask(false, false, false, true); | 
| - m_gl->Clear(GL_COLOR_BUFFER_BIT); | 
| - m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| - info.parameters.target, 0, 0); | 
| - m_gl->DeleteFramebuffers(1, &fbo); | 
| - restoreFramebufferBindings(); | 
| - m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], | 
| - m_clearColor[3]); | 
| - m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], | 
| - m_colorMask[3]); | 
| -} | 
| - | 
| -RefPtr<DrawingBuffer::ColorBuffer> | 
| -DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size) { | 
| - if (!shouldUseChromiumImage()) | 
| - return createDefaultTextureAndAllocateMemory(size); | 
| + // Allocate the texture for this object. | 
| + GLuint textureId = 0; | 
| + { | 
| + m_gl->GenTextures(1, &textureId); | 
| + m_gl->BindTexture(parameters.target, textureId); | 
| + m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
| + m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
| + m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
| + m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
| + } | 
| - TextureParameters parameters = chromiumImageTextureParameters(); | 
| - GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( | 
| - size.width(), size.height(), parameters.creationInternalColorFormat, | 
| - GC3D_SCANOUT_CHROMIUM); | 
| - GLuint textureId = createColorTexture(parameters); | 
| + // If this is GpuMemoryBuffer-backed, then bind the texture to the | 
| + // GpuMemoryBuffer's GLImage. Otherwise, allocate ordinary texture storage. | 
| if (imageId) { | 
| m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId); | 
| + } else { | 
| + if (m_storageTextureSupported) { | 
| + GLenum internalStorageFormat = GL_NONE; | 
| + if (parameters.creationInternalColorFormat == GL_RGB) { | 
| + internalStorageFormat = GL_RGB8; | 
| + } else if (parameters.creationInternalColorFormat == GL_RGBA) { | 
| + internalStorageFormat = GL_RGBA8; | 
| + } else { | 
| + NOTREACHED(); | 
| + } | 
| + m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, | 
| + size.width(), size.height()); | 
| + } else { | 
| + m_gl->TexImage2D(parameters.target, 0, | 
| + parameters.creationInternalColorFormat, size.width(), | 
| + size.height(), 0, parameters.colorFormat, | 
| + GL_UNSIGNED_BYTE, 0); | 
| + } | 
| } | 
| - RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size))); | 
| - info->textureId = textureId; | 
| - info->imageId = imageId; | 
| - clearChromiumImageAlpha(*info); | 
| - return info; | 
| -} | 
| + // Clear the alpha channel if this is RGB emulated. | 
| + if (contextProvider()->getCapabilities().chromium_image_rgb_emulation && | 
| + !m_wantAlphaChannel) { | 
| 
Ken Russell (switch to Gerrit)
2016/10/07 03:33:53
Should this code path also be gated on shouldUseCh
 
ccameron
2016/10/07 08:28:23
Yes, good catch. I've conditionalized this on havi
 | 
| + GLuint fbo = 0; | 
| + m_gl->GenFramebuffers(1, &fbo); | 
| + m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 
| + m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| + parameters.target, textureId, 0); | 
| + m_gl->ClearColor(0, 0, 0, 1); | 
| + m_gl->ColorMask(false, false, false, true); | 
| + m_gl->Clear(GL_COLOR_BUFFER_BIT); | 
| + m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| + parameters.target, 0, 0); | 
| + m_gl->DeleteFramebuffers(1, &fbo); | 
| + restoreFramebufferBindings(); | 
| + m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], | 
| + m_clearColor[3]); | 
| + m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], | 
| + m_colorMask[3]); | 
| + } | 
| -RefPtr<DrawingBuffer::ColorBuffer> | 
| -DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size) { | 
| - TextureParameters parameters = defaultTextureParameters(); | 
| - RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size))); | 
| - info->textureId = createColorTexture(parameters); | 
| - allocateConditionallyImmutableTexture( | 
| - parameters.target, parameters.creationInternalColorFormat, size.width(), | 
| - size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE); | 
| - return info; | 
| + return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); | 
| } | 
| void DrawingBuffer::attachColorBufferToReadFramebuffer() { |