Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp |
| index 1517d4c9b19f95dcf87f6717a625b5bf6c13955b..fae364a5566d711d094b86ed48ae922096b17131 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp |
| @@ -6,16 +6,13 @@ |
| #include "gpu/command_buffer/client/gles2_interface.h" |
| #include "gpu/command_buffer/common/sync_token.h" |
| -#include "platform/CrossThreadFunctional.h" |
| -#include "platform/graphics/StaticBitmapImage.h" |
| +#include "platform/graphics/MailboxTextureHolder.h" |
| +#include "platform/graphics/SkiaTextureHolder.h" |
| #include "platform/graphics/gpu/SharedGpuContext.h" |
| #include "platform/graphics/skia/SkiaUtils.h" |
| #include "public/platform/Platform.h" |
| #include "public/platform/WebGraphicsContext3DProvider.h" |
| -#include "public/platform/WebTaskRunner.h" |
| -#include "skia/ext/texture_handle.h" |
| #include "third_party/skia/include/core/SkImage.h" |
| -#include "third_party/skia/include/gpu/GrContext.h" |
| #include "wtf/PtrUtil.h" |
| #include <memory> |
| @@ -31,41 +28,40 @@ AcceleratedStaticBitmapImage::createFromSharedContextImage( |
| PassRefPtr<AcceleratedStaticBitmapImage> |
| AcceleratedStaticBitmapImage::createFromWebGLContextImage( |
| - sk_sp<SkImage> image, |
| const gpu::Mailbox& mailbox, |
| - const gpu::SyncToken& syncToken) { |
| - return adoptRef( |
| - new AcceleratedStaticBitmapImage(std::move(image), mailbox, syncToken)); |
| + const gpu::SyncToken& syncToken, |
| + unsigned textureId, |
| + WeakPtr<DrawingBuffer> drawingBuffer, |
| + IntSize mailboxSize) { |
| + return adoptRef(new AcceleratedStaticBitmapImage( |
| + mailbox, syncToken, textureId, drawingBuffer, mailboxSize)); |
| } |
| -AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image) |
| - : StaticBitmapImage(std::move(image)), |
| - m_sharedContextId(SharedGpuContext::contextId()) { |
| +AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( |
| + sk_sp<SkImage> image) { |
| + m_textureHolder = wrapUnique(new SkiaTextureHolder(std::move(image))); |
| m_threadChecker.DetachFromThread(); |
| } |
| AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( |
| - sk_sp<SkImage> image, |
| const gpu::Mailbox& mailbox, |
| - const gpu::SyncToken& syncToken) |
| - : StaticBitmapImage(std::move(image)), |
| - m_sharedContextId(SharedGpuContext::kNoSharedContext), |
| - m_hasMailbox(true), |
| - m_mailbox(mailbox), |
| - m_syncToken(syncToken) { |
| + const gpu::SyncToken& syncToken, |
| + unsigned textureId, |
| + WeakPtr<DrawingBuffer> drawingBuffer, |
| + IntSize mailboxSize) { |
| + m_textureHolder = wrapUnique(new MailboxTextureHolder( |
| + mailbox, syncToken, textureId, drawingBuffer, mailboxSize)); |
| m_threadChecker.DetachFromThread(); |
| +} |
| - // Note: In this case, m_image is not usable directly because it is not in the |
| - // shared context. It is just used to hold a reference to the texture object |
| - // in the origin context until the mailbox can be consumed. |
| +AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() {} |
| + |
| +IntSize AcceleratedStaticBitmapImage::size() const { |
| + return m_textureHolder->size(); |
| } |
| -AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() { |
| - // Avoid leaking mailboxes in cases where the texture gets recycled by skia. |
| - if (m_hasMailbox && SharedGpuContext::isValid()) |
| - SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, |
| - m_mailbox.name); |
| - releaseImageThreadSafe(); |
| +void AcceleratedStaticBitmapImage::updateSyncToken(gpu::SyncToken syncToken) { |
| + m_textureHolder->updateSyncToken(syncToken); |
| } |
| void AcceleratedStaticBitmapImage::copyToTexture( |
| @@ -83,9 +79,9 @@ void AcceleratedStaticBitmapImage::copyToTexture( |
| // Get a texture id that |destProvider| knows about and copy from it. |
| gpu::gles2::GLES2Interface* destGL = destProvider->contextGL(); |
| - destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); |
| - GLuint sourceTextureId = |
| - destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| + destGL->WaitSyncTokenCHROMIUM(m_textureHolder->syncToken().GetData()); |
| + GLuint sourceTextureId = destGL->CreateAndConsumeTextureCHROMIUM( |
| + GL_TEXTURE_2D, m_textureHolder->mailbox().name); |
| destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, |
| destType, flipY, false, false); |
| // This drops the |destGL| context's reference on our |m_mailbox|, but it's |
| @@ -98,116 +94,67 @@ sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() { |
| if (!isValid()) |
| return nullptr; |
| createImageFromMailboxIfNeeded(); |
| - return m_image; |
| + return m_textureHolder->skImage(); |
| } |
| -void AcceleratedStaticBitmapImage::draw( |
| - SkCanvas* canvas, |
| - const SkPaint& paint, |
| - const FloatRect& dstRect, |
| - const FloatRect& srcRect, |
| - RespectImageOrientationEnum respectImageOrientation, |
| - ImageClampingMode imageClampingMode) { |
| +void AcceleratedStaticBitmapImage::draw(SkCanvas* canvas, |
| + const SkPaint& paint, |
| + const FloatRect& dstRect, |
| + const FloatRect& srcRect, |
| + RespectImageOrientationEnum, |
| + ImageClampingMode imageClampingMode) { |
| checkThread(); |
| if (!isValid()) |
| return; |
| createImageFromMailboxIfNeeded(); |
| - StaticBitmapImage::draw(canvas, paint, dstRect, srcRect, |
| - respectImageOrientation, imageClampingMode); |
| + sk_sp<SkImage> image = m_textureHolder->skImage(); |
| + StaticBitmapImage::drawHelper(canvas, paint, dstRect, srcRect, |
| + imageClampingMode, image); |
| } |
| bool AcceleratedStaticBitmapImage::isValid() { |
| - if (!m_image) |
| + if (!m_textureHolder) |
| return false; |
| if (!SharedGpuContext::isValid()) |
| return false; // Gpu context was lost |
| - if (imageBelongsToSharedContext() && |
| - m_sharedContextId != SharedGpuContext::contextId()) { |
| + unsigned sharedContextId = m_textureHolder->sharedContextId(); |
| + if (sharedContextId != SharedGpuContext::kNoSharedContext && |
| + sharedContextId != SharedGpuContext::contextId()) { |
| // Gpu context was lost and restored since the resource was created. |
| return false; |
| } |
| return true; |
| } |
| -bool AcceleratedStaticBitmapImage::imageBelongsToSharedContext() { |
| - return m_sharedContextId != SharedGpuContext::kNoSharedContext; |
| -} |
| - |
| void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded() { |
| - if (imageBelongsToSharedContext()) |
| + if (m_textureHolder->sharedContextId() != SharedGpuContext::kNoSharedContext) |
| + return; |
| + if (m_textureHolder->isSkiaTextureHolder()) |
| return; |
| - DCHECK(m_hasMailbox); |
| - gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); |
| - GrContext* sharedGrContext = SharedGpuContext::gr(); |
| - DCHECK(sharedGL && |
| - sharedGrContext); // context isValid already checked in callers |
| - |
| - sharedGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); |
| - GLuint sharedContextTextureId = |
| - sharedGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| - GrGLTextureInfo textureInfo; |
| - textureInfo.fTarget = GL_TEXTURE_2D; |
| - textureInfo.fID = sharedContextTextureId; |
| - GrBackendTextureDesc backendTexture; |
| - backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin; |
| - backendTexture.fWidth = size().width(); |
| - backendTexture.fHeight = size().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(); |
| + m_textureHolder = |
| + wrapUnique(new SkiaTextureHolder(std::move(m_textureHolder))); |
| } |
| void AcceleratedStaticBitmapImage::ensureMailbox() { |
| - if (m_hasMailbox) |
| + if (m_textureHolder->isMailboxTextureHolder()) |
| return; |
| - DCHECK(m_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(m_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_hasMailbox = true; |
| + m_textureHolder = |
| + wrapUnique(new MailboxTextureHolder(std::move(m_textureHolder))); |
| } |
| void AcceleratedStaticBitmapImage::transfer() { |
| checkThread(); |
| ensureMailbox(); |
| - m_sharedContextId = SharedGpuContext::kNoSharedContext; |
| - // If |m_imageThread| is set, it means that the image has been consumed on the |
| - // current thread, which may happen when we have chained transfers. When that |
| - // is the case, we must not reset |m_imageThread|, so we ensure that |
| - // releaseImage() is called on the right thread. |
| - if (!m_imageThread) |
| - m_imageThread = Platform::current()->currentThread(); |
| m_detachThreadAtNextCheck = true; |
| } |
| +bool AcceleratedStaticBitmapImage::currentFrameKnownToBeOpaque(MetadataMode) { |
| + if (m_textureHolder->isSkiaTextureHolder()) |
|
Justin Novosad
2016/11/03 17:37:47
You should avoid explicit type checking here. jus
xidachen
2016/11/03 20:03:10
Done.
|
| + return m_textureHolder->skImage()->isOpaque(); |
| + return true; |
|
Justin Novosad
2016/11/03 17:37:47
The mailbox case should return false.
xidachen
2016/11/03 20:03:10
Done.
|
| +} |
| + |
| void AcceleratedStaticBitmapImage::checkThread() { |
| if (m_detachThreadAtNextCheck) { |
| m_threadChecker.DetachFromThread(); |
| @@ -216,31 +163,4 @@ void AcceleratedStaticBitmapImage::checkThread() { |
| CHECK(m_threadChecker.CalledOnValidThread()); |
| } |
| -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 AcceleratedStaticBitmapImage::releaseImageThreadSafe() { |
| - // If m_image belongs to a GrContext that is on another thread, it |
| - // must be released on that thread. |
| - if (m_imageThread && m_image && |
| - m_imageThread != 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_imageThread->getWebTaskRunner()->postTask( |
| - BLINK_FROM_HERE, |
| - crossThreadBind(&releaseImage, passed(std::move(m_image)), |
| - passed(std::move(releaseSyncToken)))); |
| - } |
| - m_image = nullptr; |
| - m_imageThread = nullptr; |
| -} |
| - |
| } // namespace blink |