Chromium Code Reviews| 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..f6999d3f4946f62198b5b0c315ae2428971aaac9 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/platform/graphics/SkiaTextureHolder.cpp |
| @@ -0,0 +1,91 @@ |
| +// 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 "public/platform/WebTaskRunner.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_imageThreadTaskRunner.get()->isCloneOf( |
| + Platform::current()->currentThread()->getWebTaskRunner()) && |
|
xidachen
2016/11/04 02:23:35
haraken@: The problem is in here. Let's give an ex
|
| + 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_imageThreadTaskRunner = nullptr; |
| +} |
| + |
| +} // namespace blink |