Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..413905db388e452f80ed2cd067a0158612e5b89e |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp |
| @@ -0,0 +1,107 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "platform/graphics/MailboxTextureHolder.h" |
| + |
| +#include "gpu/command_buffer/client/gles2_interface.h" |
| +#include "platform/CrossThreadFunctional.h" |
| +#include "platform/graphics/SkiaTextureHolder.h" |
| +#include "platform/graphics/WebGraphicsContext3DProviderWrapper.h" |
| +#include "platform/graphics/gpu/SharedGpuContext.h" |
| +#include "public/platform/Platform.h" |
| +#include "skia/ext/texture_handle.h" |
| +#include "third_party/skia/include/gpu/GrContext.h" |
| + |
| +namespace blink { |
| + |
| +MailboxTextureHolder::MailboxTextureHolder( |
| + const gpu::Mailbox& mailbox, |
| + const gpu::SyncToken& syncToken, |
| + unsigned textureIdToDeleteAfterMailboxConsumed, |
| + WeakPtr<WebGraphicsContext3DProviderWrapper> contextProvider, |
| + IntSize mailboxSize) |
| + : m_mailbox(mailbox), |
| + m_syncToken(syncToken), |
| + m_textureId(textureIdToDeleteAfterMailboxConsumed), |
| + m_contextProvider(contextProvider), |
| + m_size(mailboxSize), |
| + m_isConvertedFromSkiaTexture(false) {} |
| + |
| +MailboxTextureHolder::MailboxTextureHolder( |
| + std::unique_ptr<TextureHolder> textureHolder) { |
| + DCHECK(textureHolder->isSkiaTextureHolder()); |
| + sk_sp<SkImage> image = textureHolder->skImage(); |
| + DCHECK(image); |
| + |
| + gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); |
| + GrContext* sharedGrContext = SharedGpuContext::gr(); |
| + if (!sharedGrContext) { |
| + // Can happen if the context is lost. The SkImage won't be any good now |
| + // anyway. |
| + return; |
| + } |
| + GLuint imageTextureId = |
| + skia::GrBackendObjectToGrGLTextureInfo(image->getTextureHandle(true)) |
| + ->fID; |
| + sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId); |
| + |
| + sharedGL->GenMailboxCHROMIUM(m_mailbox.name); |
| + sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| + const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); |
| + sharedGL->Flush(); |
| + sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData()); |
| + |
| + sharedGL->BindTexture(GL_TEXTURE_2D, 0); |
| + // We changed bound textures in this function, so reset the GrContext. |
| + sharedGrContext->resetContext(kTextureBinding_GrGLBackendState); |
| + m_size = IntSize(image->width(), image->height()); |
| + m_textureId = imageTextureId; |
| + m_isConvertedFromSkiaTexture = true; |
| +} |
| + |
| +MailboxTextureHolder::~MailboxTextureHolder() { |
| + // Avoid leaking mailboxes in cases where the texture gets recycled by skia. |
| + if (SharedGpuContext::isValid()) { |
| + SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, |
| + m_mailbox.name); |
| + } |
| + releaseTextureThreadSafe(); |
| +} |
| + |
| +static void releaseTexture( |
|
Justin Novosad
2016/11/08 19:38:54
should use unnamed namespace instead of 'static'.
xidachen
2016/11/08 20:30:57
Done.
|
| + bool isConvertedFromSkiaTexture, |
| + unsigned textureId, |
| + WeakPtr<WebGraphicsContext3DProviderWrapper> contextProvider, |
| + std::unique_ptr<gpu::SyncToken> syncToken) { |
|
Justin Novosad
2016/11/08 19:02:18
Why not just pass sync token by value? It is a POD
|
| + if (!isConvertedFromSkiaTexture && textureId && contextProvider) { |
| + contextProvider->contextProvider()->contextGL()->WaitSyncTokenCHROMIUM( |
| + syncToken->GetData()); |
|
xidachen
2016/11/08 18:46:07
junov@: it is crashing at syncToken->GetData(). I
|
| + contextProvider->contextProvider()->contextGL()->DeleteTextures(1, |
| + &textureId); |
| + } |
| +} |
| + |
| +void MailboxTextureHolder::releaseTextureThreadSafe() { |
| + // If this member is still null, it means we are still at the thread where |
| + // the m_texture was created. |
| + std::unique_ptr<gpu::SyncToken> passedSyncToken( |
| + new gpu::SyncToken(m_syncToken)); |
| + if (!m_textureThreadDoNotCall) { |
| + releaseTexture(m_isConvertedFromSkiaTexture, m_textureId, m_contextProvider, |
| + std::move(passedSyncToken)); |
|
xidachen
2016/11/08 19:07:10
Also, I found that if I replace this releaseTextur
|
| + } else if (m_textureThreadDoNotCall && m_textureThreadTaskRunner) { |
| + m_textureThreadTaskRunner->postTask( |
| + BLINK_FROM_HERE, |
| + crossThreadBind(&releaseTexture, m_isConvertedFromSkiaTexture, |
| + m_textureId, passed(std::move(m_contextProvider)), |
| + passed(std::move(passedSyncToken)))); |
|
xidachen
2016/11/08 19:07:10
we have to do a crossThreadBind to call the releas
|
| + } |
| + m_textureId = 0u; // invalidate the texture. |
| +} |
| + |
| +unsigned MailboxTextureHolder::sharedContextId() { |
| + return SharedGpuContext::kNoSharedContext; |
| +} |
| + |
| +} // namespace blink |