Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(575)

Unified Diff: third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp

Issue 2261623002: Make DrawingBuffer and Canvas2DLayerBridge be cc::TextureLayerClients. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: webmailbox: fix-passrefptr Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 4edc487659396e3618008b615538eeab3ef0b13e..0ec750ec1b6c1019be6bd2499f8338e5872d67da 100644
--- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp
@@ -5,6 +5,7 @@
#include "platform/graphics/AcceleratedStaticBitmapImage.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/sync_token.h"
#include "platform/graphics/StaticBitmapImage.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "public/platform/Platform.h"
@@ -13,138 +14,123 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "wtf/PtrUtil.h"
+
#include <memory>
+#include <utility>
namespace blink {
-PassRefPtr<AcceleratedStaticBitmapImage> AcceleratedStaticBitmapImage::create(WebExternalTextureMailbox& mailbox)
-{
- return adoptRef(new AcceleratedStaticBitmapImage(mailbox));
-}
-
PassRefPtr<AcceleratedStaticBitmapImage> AcceleratedStaticBitmapImage::create(PassRefPtr<SkImage> image)
{
return adoptRef(new AcceleratedStaticBitmapImage(image));
}
-AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(WebExternalTextureMailbox& mailbox)
- : StaticBitmapImage()
- , m_mailbox(mailbox)
+PassRefPtr<AcceleratedStaticBitmapImage> AcceleratedStaticBitmapImage::create(PassRefPtr<SkImage> image, sk_sp<GrContext> grContext, const gpu::Mailbox& mailbox, const gpu::SyncToken& syncToken)
{
+ return adoptRef(new AcceleratedStaticBitmapImage(image, std::move(grContext), mailbox, syncToken));
}
AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(PassRefPtr<SkImage> image)
- : StaticBitmapImage(image)
+ : StaticBitmapImage(std::move(image))
+ , m_imageIsForSharedMainThreadContext(true)
{
}
-IntSize AcceleratedStaticBitmapImage::size() const
+AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(PassRefPtr<SkImage> image, sk_sp<GrContext> grContext, const gpu::Mailbox& mailbox, const gpu::SyncToken& syncToken)
+ : StaticBitmapImage(std::move(image))
+ , m_imageIsForSharedMainThreadContext(false) // TODO(danakj): Could be true though, caller would know.
+ , m_grContext(std::move(grContext))
+ , m_hasMailbox(true)
+ , m_mailbox(mailbox)
+ , m_syncToken(syncToken)
{
- if (m_image)
- return IntSize(m_image->width(), m_image->height());
- return IntSize(m_mailbox.textureSize.width, m_mailbox.textureSize.height);
+ DCHECK(m_grContext);
}
-void AcceleratedStaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* provider, GLuint destinationTexture, GLenum internalFormat, GLenum destType, bool flipY)
-{
- GLuint textureId = switchStorageToSkImageForWebGL(provider);
- gpu::gles2::GLES2Interface* gl = provider->contextGL();
- if (!gl)
- return;
- gl->CopyTextureCHROMIUM(textureId, destinationTexture, internalFormat, destType, flipY, false, false);
- const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
- gl->Flush();
- GLbyte syncToken[24];
- gl->GenSyncTokenCHROMIUM(fenceSync, syncToken);
- // Get a new mailbox because we cannot retain a texture in the WebGL context.
- switchStorageToMailbox(provider);
-}
+AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() = default;
-bool AcceleratedStaticBitmapImage::switchStorageToMailbox(WebGraphicsContext3DProvider* provider)
+void AcceleratedStaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* destProvider, GLuint destTextureId, GLenum internalFormat, GLenum destType, bool flipY)
{
- m_mailbox.textureSize = WebSize(m_image->width(), m_image->height());
- GrContext* grContext = provider->grContext();
- if (!grContext)
- return false;
- grContext->flush();
- m_mailbox.textureTarget = GL_TEXTURE_2D;
- gpu::gles2::GLES2Interface* gl = provider->contextGL();
- if (!gl)
- return false;
- GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true))->fID;
- gl->BindTexture(GL_TEXTURE_2D, textureID);
-
- gl->GenMailboxCHROMIUM(m_mailbox.name);
- gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
- const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
- gl->Flush();
- gl->GenSyncTokenCHROMIUM(fenceSync, m_mailbox.syncToken);
- m_mailbox.validSyncToken = true;
- gl->BindTexture(GL_TEXTURE_2D, 0);
- grContext->resetContext(kTextureBinding_GrGLBackendState);
- m_image = nullptr;
- return true;
-}
+ // |destProvider| may not be the same context as the one used for |m_image| so we use a mailbox to
+ // generate a texture id for |destProvider| to access.
+ ensureMailbox();
-// This function is called only in the case that m_image is texture backed.
-GLuint AcceleratedStaticBitmapImage::switchStorageToSkImageForWebGL(WebGraphicsContext3DProvider* contextProvider)
-{
- DCHECK(!m_image || m_image->isTextureBacked());
- GLuint textureId = 0;
- if (m_image) {
- // SkImage is texture-backed on the shared context
- if (!hasMailbox()) {
- std::unique_ptr<WebGraphicsContext3DProvider> sharedProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
- if (!switchStorageToMailbox(sharedProvider.get()))
- return 0;
- textureId = switchStorageToSkImage(contextProvider);
- return textureId;
- }
- }
- DCHECK(hasMailbox());
- textureId = switchStorageToSkImage(contextProvider);
- return textureId;
+ // 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->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, destType, flipY, false, false);
+ // This drops the |destGL| context's reference on our |m_mailbox|, but it's still held alive by our SkImage.
+ destGL->DeleteTextures(1, &sourceTextureId);
}
-GLuint AcceleratedStaticBitmapImage::switchStorageToSkImage(WebGraphicsContext3DProvider* provider)
+PassRefPtr<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame()
{
- if (!provider)
- return 0;
- GrContext* grContext = provider->grContext();
- if (!grContext)
- return 0;
- gpu::gles2::GLES2Interface* gl = provider->contextGL();
- if (!gl)
- return 0;
- gl->WaitSyncTokenCHROMIUM(m_mailbox.syncToken);
- GLuint textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
+ // This must return an SkImage that can be used with the shared main thread context. If |m_image| satisfies that, we are done.
+ if (m_imageIsForSharedMainThreadContext)
+ return m_image;
+
+ // TODO(xidachen): make this work on a worker thread.
+ DCHECK(isMainThread());
+
+ // If the SkImage came from any other context than the shared main thread one, we expect to be given a mailbox at construction. We
+ // use the mailbox to generate a texture id for the shared main thread context to use.
+ DCHECK(m_hasMailbox);
+
+ auto sharedMainThreadContextProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+ gpu::gles2::GLES2Interface* sharedGL = sharedMainThreadContextProvider->contextGL();
+ GrContext* sharedGrContext = sharedMainThreadContextProvider->grContext();
+ if (!sharedGrContext)
+ return nullptr; // Can happen if the context is lost, the SkImage won't be any good now anyway.
+
+ sharedGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData());
+ GLuint sharedContextTextureId = sharedGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
+
GrGLTextureInfo textureInfo;
textureInfo.fTarget = GL_TEXTURE_2D;
- textureInfo.fID = textureId;
+ textureInfo.fID = sharedContextTextureId;
GrBackendTextureDesc backendTexture;
backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
- backendTexture.fWidth = m_mailbox.textureSize.width;
- backendTexture.fHeight = m_mailbox.textureSize.height;
+ backendTexture.fWidth = size().width();
+ backendTexture.fHeight = size().height();
backendTexture.fConfig = kSkia8888_GrPixelConfig;
backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textureInfo);
- sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendTexture);
- m_image = fromSkSp(skImage);
- return textureId;
+
+ m_image = fromSkSp(SkImage::MakeFromAdoptedTexture(sharedGrContext, backendTexture));
+ m_imageIsForSharedMainThreadContext = true;
+ // Can drop the ref on the GrContext since m_image is now backed by a texture from the shared main thread context.
+ m_grContext = nullptr;
+ return m_image;
}
-PassRefPtr<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame()
+void AcceleratedStaticBitmapImage::ensureMailbox()
{
- if (m_image)
- return m_image;
- if (!hasMailbox())
- return nullptr;
- // Has mailbox, consume mailbox, prepare a new mailbox if contextProvider is not null (3D).
- DCHECK(isMainThread());
- // TODO(xidachen): make this work on a worker thread.
- std::unique_ptr<WebGraphicsContext3DProvider> sharedProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
- if (!switchStorageToSkImage(sharedProvider.get()))
- return nullptr;
- return m_image;
+ if (m_hasMailbox)
+ return;
+
+ // If we weren't given a mailbox at creation, then we were given a SkImage that is assumed to be from the shared main thread context.
+ DCHECK(m_imageIsForSharedMainThreadContext);
+ auto sharedMainThreadContextProvider = wrapUnique(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+
+ gpu::gles2::GLES2Interface* sharedGL = sharedMainThreadContextProvider->contextGL();
+ GrContext* sharedGrContext = sharedMainThreadContextProvider->grContext();
+ if (!sharedGrContext)
+ return; // Can happen if the context is lost, the SkImage won't be any good now anyway.
+
+ 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;
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698