Index: third_party/WebKit/Source/platform/graphics/SkiaTextureHolder.cpp |
diff --git a/third_party/WebKit/Source/platform/graphics/SkiaTextureHolder.cpp b/third_party/WebKit/Source/platform/graphics/SkiaTextureHolder.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ac06343321d7c186b7c3bf51378373ddfaac1d89 |
--- /dev/null |
+++ b/third_party/WebKit/Source/platform/graphics/SkiaTextureHolder.cpp |
@@ -0,0 +1,90 @@ |
+// 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/SkiaTextureHolder.h" |
+ |
+#include "gpu/command_buffer/client/gles2_interface.h" |
+#include "platform/CrossThreadFunctional.h" |
+#include "platform/graphics/MailboxTextureHolder.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 { |
+ |
+SkiaTextureHolder::SkiaTextureHolder(sk_sp<SkImage> image) |
+ : m_image(std::move(image)), |
+ m_sharedContextId(SharedGpuContext::contextId()) {} |
+ |
+SkiaTextureHolder::SkiaTextureHolder( |
+ std::unique_ptr<TextureHolder> textureHolder) { |
+ DCHECK(textureHolder->isMailboxTextureHolder()); |
+ const gpu::Mailbox mailbox = textureHolder->mailbox(); |
+ const gpu::SyncToken syncToken = textureHolder->syncToken(); |
+ const IntSize mailboxSize = textureHolder->size(); |
+ |
+ gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); |
+ GrContext* sharedGrContext = SharedGpuContext::gr(); |
+ DCHECK(sharedGL && |
+ sharedGrContext); // context isValid already checked in callers |
+ |
+ sharedGL->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); |
+ GLuint sharedContextTextureId = |
+ sharedGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
+ GrGLTextureInfo textureInfo; |
+ textureInfo.fTarget = GL_TEXTURE_2D; |
+ textureInfo.fID = sharedContextTextureId; |
+ GrBackendTextureDesc backendTexture; |
+ backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin; |
+ backendTexture.fWidth = mailboxSize.width(); |
+ backendTexture.fHeight = mailboxSize.height(); |
+ backendTexture.fConfig = kSkia8888_GrPixelConfig; |
+ backendTexture.fTextureHandle = |
+ skia::GrGLTextureInfoToGrBackendObject(textureInfo); |
+ |
+ sk_sp<SkImage> newImage = |
+ SkImage::MakeFromAdoptedTexture(sharedGrContext, backendTexture); |
+ releaseImageThreadSafe(); |
+ m_image = newImage; |
+ m_sharedContextId = SharedGpuContext::contextId(); |
+} |
+ |
+SkiaTextureHolder::~SkiaTextureHolder() { |
+ releaseImageThreadSafe(); |
+} |
+ |
+unsigned SkiaTextureHolder::sharedContextId() { |
+ return m_sharedContextId; |
+} |
+ |
+void releaseImage(sk_sp<SkImage>&& image, |
+ std::unique_ptr<gpu::SyncToken>&& syncToken) { |
+ if (SharedGpuContext::isValid() && syncToken->HasData()) |
+ SharedGpuContext::gl()->WaitSyncTokenCHROMIUM(syncToken->GetData()); |
+ image.reset(); |
+} |
+ |
+void SkiaTextureHolder::releaseImageThreadSafe() { |
+ // If m_image belongs to a GrContext that is on another thread, it |
+ // must be released on that thread. |
+ if (m_imageThreadTaskRunner && m_image && |
+ m_imageThreadDoNotCall != Platform::current()->currentThread() && |
+ SharedGpuContext::isValid()) { |
+ gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); |
+ std::unique_ptr<gpu::SyncToken> releaseSyncToken(new gpu::SyncToken); |
+ const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); |
+ sharedGL->Flush(); |
+ sharedGL->GenSyncTokenCHROMIUM(fenceSync, releaseSyncToken->GetData()); |
+ m_imageThreadTaskRunner->postTask( |
+ BLINK_FROM_HERE, |
+ crossThreadBind(&releaseImage, passed(std::move(m_image)), |
+ passed(std::move(releaseSyncToken)))); |
+ } |
+ m_image = nullptr; |
+ m_imageThreadDoNotCall = nullptr; |
+ m_imageThreadTaskRunner = nullptr; |
+} |
+ |
+} // namespace blink |