| 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 25d0041ddfd0cca16a587818e68622866e3cd35e..3f203e79ab4e1599738b39018414a486acfb5f5c 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
|
| @@ -182,8 +182,7 @@ DrawingBuffer::DrawingBuffer(
|
| }
|
|
|
| DrawingBuffer::~DrawingBuffer() {
|
| - ASSERT(m_destructionInProgress);
|
| - ASSERT(m_textureMailboxes.isEmpty());
|
| + DCHECK(m_destructionInProgress);
|
| m_layer.reset();
|
| m_contextProvider.reset();
|
| }
|
| @@ -218,7 +217,7 @@ void DrawingBuffer::setIsHidden(bool hidden) {
|
| return;
|
| m_isHidden = hidden;
|
| if (m_isHidden)
|
| - freeRecycledMailboxes();
|
| + m_recycledMailboxQueue.clear();
|
| }
|
|
|
| void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) {
|
| @@ -247,13 +246,6 @@ bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() {
|
| return !m_wantAlphaChannel && rgbEmulation;
|
| }
|
|
|
| -void DrawingBuffer::freeRecycledMailboxes() {
|
| - while (!m_recycledMailboxQueue.isEmpty()) {
|
| - RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast();
|
| - deleteMailbox(recycled->mailbox, recycled->syncToken);
|
| - }
|
| -}
|
| -
|
| std::unique_ptr<cc::SharedBitmap> DrawingBuffer::createOrRecycleBitmap() {
|
| auto it = std::remove_if(
|
| m_recycledBitmaps.begin(), m_recycledBitmaps.end(),
|
| @@ -305,7 +297,7 @@ bool DrawingBuffer::prepareTextureMailboxInternal(
|
| if (m_newMailboxCallback)
|
| (*m_newMailboxCallback)();
|
|
|
| - // Resolve the multisampled buffer into m_colorBuffer texture.
|
| + // Resolve the multisampled buffer into m_backColorBuffer texture.
|
| if (m_antiAliasingMode != None)
|
| commit();
|
|
|
| @@ -346,14 +338,14 @@ bool DrawingBuffer::prepareTextureMailboxInternal(
|
| m_texture2DBinding);
|
|
|
| // First try to recycle an old buffer.
|
| - RefPtr<MailboxInfo> mailboxInfo = takeRecycledMailbox();
|
| + RefPtr<ColorBuffer> colorBufferForMailbox = takeRecycledMailbox();
|
|
|
| // No buffer available to recycle, create a new one.
|
| - if (!mailboxInfo)
|
| - mailboxInfo = createNewMailbox(createTextureAndAllocateMemory(m_size));
|
| + if (!colorBufferForMailbox)
|
| + colorBufferForMailbox = createTextureAndAllocateMemory(m_size);
|
|
|
| if (m_preserveDrawingBuffer == Discard) {
|
| - std::swap(mailboxInfo->textureInfo, m_colorBuffer);
|
| + std::swap(colorBufferForMailbox, m_backColorBuffer);
|
| attachColorBufferToReadFramebuffer();
|
|
|
| if (m_discardFramebufferSupported) {
|
| @@ -366,17 +358,17 @@ bool DrawingBuffer::prepareTextureMailboxInternal(
|
| }
|
| } else {
|
| m_gl->CopySubTextureCHROMIUM(
|
| - m_colorBuffer.textureId, mailboxInfo->textureInfo.textureId, 0, 0, 0, 0,
|
| - m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
|
| + 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(mailboxInfo->textureInfo.textureId,
|
| - mailboxInfo->textureInfo.parameters.target,
|
| - mailboxInfo->mailbox.name);
|
| + m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId,
|
| + colorBufferForMailbox->parameters.target,
|
| + colorBufferForMailbox->mailbox.name);
|
| const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
|
| #if OS(MACOSX)
|
| m_gl->DescheduleUntilFinishedCHROMIUM();
|
| @@ -385,33 +377,43 @@ bool DrawingBuffer::prepareTextureMailboxInternal(
|
| gpu::SyncToken syncToken;
|
| m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
|
|
|
| - bool isOverlayCandidate = mailboxInfo->textureInfo.imageId != 0;
|
| + bool isOverlayCandidate = colorBufferForMailbox->imageId != 0;
|
| bool secureOutputOnly = false;
|
| - *outMailbox = cc::TextureMailbox(mailboxInfo->mailbox, syncToken,
|
| - mailboxInfo->textureInfo.parameters.target,
|
| + *outMailbox = cc::TextureMailbox(colorBufferForMailbox->mailbox, syncToken,
|
| + colorBufferForMailbox->parameters.target,
|
| gfx::Size(m_size.width(), m_size.height()),
|
| 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), mailboxInfo->mailbox);
|
| + RefPtr<DrawingBuffer>(this), colorBufferForMailbox);
|
| *outReleaseCallback =
|
| cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func)));
|
|
|
| - m_frontColorBuffer = {mailboxInfo->mailbox, syncToken,
|
| - mailboxInfo->textureInfo};
|
| + // Point |m_frontColorBuffer| to the buffer that we are presenting, and
|
| + // update its sync token.
|
| + colorBufferForMailbox->produceSyncToken = syncToken;
|
| + m_frontColorBuffer = colorBufferForMailbox;
|
| setBufferClearNeeded(true);
|
| return true;
|
| }
|
|
|
| -void DrawingBuffer::gpuMailboxReleased(const gpu::Mailbox& mailbox,
|
| +void DrawingBuffer::gpuMailboxReleased(RefPtr<ColorBuffer> colorBuffer,
|
| const gpu::SyncToken& syncToken,
|
| bool lostResource) {
|
| - if (m_destructionInProgress ||
|
| + // If the mailbox has been returned by the compositor then it is no
|
| + // longer being presented, and so is no longer the front buffer.
|
| + if (colorBuffer == m_frontColorBuffer)
|
| + m_frontColorBuffer = nullptr;
|
| +
|
| + // Update the SyncToken to ensure that we will wait for it even if we
|
| + // immediately destroy this buffer.
|
| + colorBuffer->receiveSyncToken = syncToken;
|
| +
|
| + if (m_destructionInProgress || colorBuffer->size != m_size ||
|
| m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource ||
|
| m_isHidden) {
|
| - deleteMailbox(mailbox, syncToken);
|
| return;
|
| }
|
|
|
| @@ -420,26 +422,10 @@ void DrawingBuffer::gpuMailboxReleased(const gpu::Mailbox& mailbox,
|
| size_t cacheLimit = 1;
|
| if (shouldUseChromiumImage())
|
| cacheLimit = 4;
|
| - while (m_recycledMailboxQueue.size() >= cacheLimit) {
|
| - RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast();
|
| - deleteMailbox(recycled->mailbox, recycled->syncToken);
|
| - }
|
| + while (m_recycledMailboxQueue.size() >= cacheLimit)
|
| + m_recycledMailboxQueue.takeLast();
|
|
|
| - RefPtr<MailboxInfo> mailboxInfo;
|
| - for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
|
| - if (m_textureMailboxes[i]->mailbox == mailbox) {
|
| - mailboxInfo = m_textureMailboxes[i];
|
| - break;
|
| - }
|
| - }
|
| - DCHECK(mailboxInfo);
|
| - if (mailboxInfo->size != m_size) {
|
| - deleteMailbox(mailbox, syncToken);
|
| - return;
|
| - }
|
| -
|
| - m_recycledMailboxQueue.prepend(
|
| - adoptRef(new RecycledMailbox(mailbox, syncToken)));
|
| + m_recycledMailboxQueue.prepend(colorBuffer);
|
| }
|
|
|
| void DrawingBuffer::softwareMailboxReleased(
|
| @@ -582,49 +568,34 @@ DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() {
|
| return parameters;
|
| }
|
|
|
| -PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::takeRecycledMailbox() {
|
| +PassRefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::takeRecycledMailbox() {
|
| if (m_recycledMailboxQueue.isEmpty())
|
| return nullptr;
|
|
|
| - RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast();
|
| - if (recycled->syncToken.HasData())
|
| - m_gl->WaitSyncTokenCHROMIUM(recycled->syncToken.GetData());
|
| -
|
| - RefPtr<MailboxInfo> mailboxInfo;
|
| - for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
|
| - if (m_textureMailboxes[i]->mailbox == recycled->mailbox) {
|
| - mailboxInfo = m_textureMailboxes[i];
|
| - break;
|
| - }
|
| - }
|
| - DCHECK(mailboxInfo);
|
| - DCHECK(mailboxInfo->size == m_size);
|
| - return mailboxInfo.release();
|
| + 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::MailboxInfo> DrawingBuffer::createNewMailbox(
|
| - const TextureInfo& info) {
|
| - RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo);
|
| - m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name);
|
| - returnMailbox->textureInfo = info;
|
| - returnMailbox->size = m_size;
|
| - m_textureMailboxes.append(returnMailbox);
|
| - return returnMailbox.release();
|
| +DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer,
|
| + const TextureParameters& parameters,
|
| + const IntSize& size)
|
| + : drawingBuffer(drawingBuffer), parameters(parameters), size(size) {
|
| + drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name);
|
| }
|
|
|
| -void DrawingBuffer::deleteMailbox(const gpu::Mailbox& mailbox,
|
| - const gpu::SyncToken& syncToken) {
|
| - if (syncToken.HasData())
|
| - m_gl->WaitSyncTokenCHROMIUM(syncToken.GetConstData());
|
| - for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
|
| - if (m_textureMailboxes[i]->mailbox == mailbox) {
|
| - deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo);
|
| - m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureId);
|
| - m_textureMailboxes.remove(i);
|
| - return;
|
| - }
|
| +DrawingBuffer::ColorBuffer::~ColorBuffer() {
|
| + gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL();
|
| + if (receiveSyncToken.HasData())
|
| + gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData());
|
| + if (imageId) {
|
| + gl->BindTexture(parameters.target, textureId);
|
| + gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId);
|
| + gl->DestroyImageCHROMIUM(imageId);
|
| }
|
| - ASSERT_NOT_REACHED();
|
| + gl->DeleteTextures(1, &textureId);
|
| }
|
|
|
| bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) {
|
| @@ -706,20 +677,18 @@ bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl,
|
|
|
| // Contexts may be in a different share group. We must transfer the texture
|
| // through a mailbox first.
|
| - GLint textureId = 0;
|
| GLenum target = 0;
|
| gpu::Mailbox mailbox;
|
| gpu::SyncToken produceSyncToken;
|
| - if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
|
| - textureId = m_frontColorBuffer.texInfo.textureId;
|
| - target = m_frontColorBuffer.texInfo.parameters.target;
|
| - mailbox = m_frontColorBuffer.mailbox;
|
| - produceSyncToken = m_frontColorBuffer.produceSyncToken;
|
| + if (sourceBuffer == FrontBuffer && m_frontColorBuffer) {
|
| + target = m_frontColorBuffer->parameters.target;
|
| + mailbox = m_frontColorBuffer->mailbox;
|
| + produceSyncToken = m_frontColorBuffer->produceSyncToken;
|
| } else {
|
| - textureId = m_colorBuffer.textureId;
|
| - target = m_colorBuffer.parameters.target;
|
| + target = m_backColorBuffer->parameters.target;
|
| m_gl->GenMailboxCHROMIUM(mailbox.name);
|
| - m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name);
|
| + m_gl->ProduceTextureDirectCHROMIUM(m_backColorBuffer->textureId, target,
|
| + mailbox.name);
|
| const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
|
| m_gl->Flush();
|
| m_gl->GenSyncTokenCHROMIUM(fenceSync, produceSyncToken.GetData());
|
| @@ -785,7 +754,7 @@ void DrawingBuffer::beginDestruction() {
|
| m_destructionInProgress = true;
|
|
|
| clearPlatformLayer();
|
| - freeRecycledMailboxes();
|
| + m_recycledMailboxQueue.clear();
|
|
|
| if (m_multisampleFBO)
|
| m_gl->DeleteFramebuffers(1, &m_multisampleFBO);
|
| @@ -799,15 +768,10 @@ void DrawingBuffer::beginDestruction() {
|
| if (m_depthStencilBuffer)
|
| m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer);
|
|
|
| - if (m_colorBuffer.textureId) {
|
| - deleteChromiumImageForTexture(&m_colorBuffer);
|
| - m_gl->DeleteTextures(1, &m_colorBuffer.textureId);
|
| - }
|
| -
|
| m_size = IntSize();
|
|
|
| - m_colorBuffer = TextureInfo();
|
| - m_frontColorBuffer = FrontBufferInfo();
|
| + m_backColorBuffer = nullptr;
|
| + m_frontColorBuffer = nullptr;
|
| m_multisampleRenderbuffer = 0;
|
| m_depthStencilBuffer = 0;
|
| m_multisampleFBO = 0;
|
| @@ -829,12 +793,8 @@ GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) {
|
| }
|
|
|
| bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) {
|
| - // Resize or create m_colorBuffer.
|
| - if (m_colorBuffer.textureId) {
|
| - deleteChromiumImageForTexture(&m_colorBuffer);
|
| - m_gl->DeleteTextures(1, &m_colorBuffer.textureId);
|
| - }
|
| - m_colorBuffer = createTextureAndAllocateMemory(size);
|
| + // Recreate m_backColorBuffer.
|
| + m_backColorBuffer = createTextureAndAllocateMemory(size);
|
|
|
| attachColorBufferToReadFramebuffer();
|
|
|
| @@ -936,7 +896,8 @@ 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.
|
| - freeRecycledMailboxes();
|
| + m_recycledMailboxQueue.clear();
|
| + m_recycledBitmaps.clear();
|
|
|
| if (adjustedSize.isEmpty())
|
| return false;
|
| @@ -1069,12 +1030,12 @@ bool DrawingBuffer::paintRenderingResultsToImageData(
|
| WTF::ArrayBufferContents::DontInitialize);
|
|
|
| GLuint fbo = 0;
|
| - if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) {
|
| + if (sourceBuffer == FrontBuffer && m_frontColorBuffer) {
|
| m_gl->GenFramebuffers(1, &fbo);
|
| m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
|
| m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| - m_frontColorBuffer.texInfo.parameters.target,
|
| - m_frontColorBuffer.texInfo.textureId, 0);
|
| + m_frontColorBuffer->parameters.target,
|
| + m_frontColorBuffer->textureId, 0);
|
| } else {
|
| m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer());
|
| }
|
| @@ -1085,8 +1046,7 @@ bool DrawingBuffer::paintRenderingResultsToImageData(
|
|
|
| if (fbo) {
|
| m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| - m_frontColorBuffer.texInfo.parameters.target, 0,
|
| - 0);
|
| + m_frontColorBuffer->parameters.target, 0, 0);
|
| m_gl->DeleteFramebuffers(1, &fbo);
|
| }
|
|
|
| @@ -1170,16 +1130,7 @@ void DrawingBuffer::allocateConditionallyImmutableTexture(GLenum target,
|
| type, 0);
|
| }
|
|
|
| -void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info) {
|
| - if (info->imageId) {
|
| - m_gl->BindTexture(info->parameters.target, info->textureId);
|
| - m_gl->ReleaseTexImage2DCHROMIUM(info->parameters.target, info->imageId);
|
| - m_gl->DestroyImageCHROMIUM(info->imageId);
|
| - info->imageId = 0;
|
| - }
|
| -}
|
| -
|
| -void DrawingBuffer::clearChromiumImageAlpha(const TextureInfo& info) {
|
| +void DrawingBuffer::clearChromiumImageAlpha(const ColorBuffer& info) {
|
| if (m_wantAlphaChannel)
|
| return;
|
| if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation)
|
| @@ -1203,8 +1154,8 @@ void DrawingBuffer::clearChromiumImageAlpha(const TextureInfo& info) {
|
| m_colorMask[3]);
|
| }
|
|
|
| -DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory(
|
| - const IntSize& size) {
|
| +RefPtr<DrawingBuffer::ColorBuffer>
|
| +DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size) {
|
| if (!shouldUseChromiumImage())
|
| return createDefaultTextureAndAllocateMemory(size);
|
|
|
| @@ -1217,20 +1168,18 @@ DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory(
|
| m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId);
|
| }
|
|
|
| - TextureInfo info;
|
| - info.textureId = textureId;
|
| - info.imageId = imageId;
|
| - info.parameters = parameters;
|
| - clearChromiumImageAlpha(info);
|
| + RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size)));
|
| + info->textureId = textureId;
|
| + info->imageId = imageId;
|
| + clearChromiumImageAlpha(*info);
|
| return info;
|
| }
|
|
|
| -DrawingBuffer::TextureInfo DrawingBuffer::createDefaultTextureAndAllocateMemory(
|
| - const IntSize& size) {
|
| - DrawingBuffer::TextureInfo info;
|
| +RefPtr<DrawingBuffer::ColorBuffer>
|
| +DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size) {
|
| TextureParameters parameters = defaultTextureParameters();
|
| - info.parameters = parameters;
|
| - info.textureId = createColorTexture(parameters);
|
| + 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);
|
| @@ -1240,8 +1189,8 @@ DrawingBuffer::TextureInfo DrawingBuffer::createDefaultTextureAndAllocateMemory(
|
| void DrawingBuffer::attachColorBufferToReadFramebuffer() {
|
| m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
|
|
| - GLenum target = m_colorBuffer.parameters.target;
|
| - GLenum id = m_colorBuffer.textureId;
|
| + GLenum target = m_backColorBuffer->parameters.target;
|
| + GLenum id = m_backColorBuffer->textureId;
|
|
|
| m_gl->BindTexture(target, id);
|
|
|
|
|