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..3790e3864a517584e3f8f1a8d941a1dde86ba667 |
--- /dev/null |
+++ b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp |
@@ -0,0 +1,112 @@ |
+// 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/gpu/SharedGpuContext.h" |
+#include "public/platform/Platform.h" |
+#include "skia/ext/texture_handle.h" |
+#include "third_party/skia/include/gpu/GrContext.h" |
+ |
+namespace blink { |
+ |
+namespace { |
+ |
+void releaseTexture( |
+ bool isConvertedFromSkiaTexture, |
+ unsigned textureId, |
+ WeakPtr<WebGraphicsContext3DProviderWrapper> contextProvider, |
+ std::unique_ptr<gpu::SyncToken> syncToken) { |
+ if (!isConvertedFromSkiaTexture && textureId && contextProvider) { |
+ contextProvider->contextProvider()->contextGL()->WaitSyncTokenCHROMIUM( |
+ syncToken->GetData()); |
+ contextProvider->contextProvider()->contextGL()->DeleteTextures(1, |
+ &textureId); |
+ } |
+} |
+ |
+} // namespace |
+ |
+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(); |
+} |
+ |
+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 (!wasTransferred()) { |
+ releaseTexture(m_isConvertedFromSkiaTexture, m_textureId, m_contextProvider, |
+ std::move(passedSyncToken)); |
+ } else if (wasTransferred() && textureThreadTaskRunner()) { |
+ textureThreadTaskRunner()->postTask( |
+ BLINK_FROM_HERE, |
+ crossThreadBind(&releaseTexture, m_isConvertedFromSkiaTexture, |
+ m_textureId, passed(std::move(m_contextProvider)), |
+ passed(std::move(passedSyncToken)))); |
+ } |
+ m_textureId = 0u; // invalidate the texture. |
+ setWasTransferred(false); |
+ setTextureThreadTaskRunner(nullptr); |
+} |
+ |
+unsigned MailboxTextureHolder::sharedContextId() { |
+ return SharedGpuContext::kNoSharedContext; |
+} |
+ |
+} // namespace blink |