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

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

Issue 2026803002: Avoid GPU readback in tex(Sub)Image2D(ImageBitmap) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: staticbitmapimage does not keep provider anymore Created 4 years, 6 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/StaticBitmapImage.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
index ac88b3d3d8c066136131b2f7aa9719f45976c96e..c5fb57326af450b9006f685fe62e3ba9f3823524 100644
--- a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.cpp
@@ -14,6 +14,7 @@
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkShader.h"
+#include "third_party/skia/include/gpu/GrContext.h"
namespace blink {
@@ -42,9 +43,16 @@ StaticBitmapImage::~StaticBitmapImage() { }
IntSize StaticBitmapImage::size() const
{
+ if (!m_image)
+ return IntSize(m_mailbox.textureSize.width, m_mailbox.textureSize.height);
return IntSize(m_image->width(), m_image->height());
}
+bool StaticBitmapImage::isTextureBacked()
+{
+ return m_image && m_image->isTextureBacked();
+}
+
bool StaticBitmapImage::currentFrameKnownToBeOpaque(MetadataMode)
{
return m_image->isOpaque();
@@ -66,28 +74,21 @@ void StaticBitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const Float
observer->didDraw(this);
}
-PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame()
+void StaticBitmapImage::consumeTextureMailbox(WebGraphicsContext3DProvider* provider)
{
- if (m_image)
- return m_image;
- DCHECK(isMainThread());
- // In the place when we consume an ImageBitmap that is gpu texture backed,
- // create a new SkImage from that texture.
- // TODO(xidachen): make this work on a worker thread.
- OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
if (!provider)
- return nullptr;
+ return;
GrContext* grContext = provider->grContext();
if (!grContext)
- return nullptr;
+ return;
gpu::gles2::GLES2Interface* gl = provider->contextGL();
if (!gl)
- return nullptr;
+ return;
gl->WaitSyncTokenCHROMIUM(m_mailbox.syncToken);
- GLuint textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
+ m_textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
GrGLTextureInfo textureInfo;
textureInfo.fTarget = GL_TEXTURE_2D;
- textureInfo.fID = textureId;
+ textureInfo.fID = m_textureId;
GrBackendTextureDesc backendTexture;
backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
backendTexture.fWidth = m_mailbox.textureSize.width;
@@ -96,6 +97,79 @@ PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame()
backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textureInfo);
sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendTexture);
m_image = fromSkSp(skImage);
+}
+
+void StaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* provider, GLuint destinationTexture, GLenum internalFormat, GLenum destType)
+{
+ gpu::gles2::GLES2Interface* gl = provider->contextGL();
+ if (!gl)
+ return;
+ gl->CopyTextureCHROMIUM(m_textureId, destinationTexture, internalFormat, destType, false, false, false);
+ const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
+ GLbyte syncToken[24];
+ gl->GenSyncTokenCHROMIUM(fenceSync, syncToken);
+}
+
+bool StaticBitmapImage::prepareMailboxForSkImage(WebGraphicsContext3DProvider* provider)
Justin Novosad 2016/06/10 17:50:40 Could we call this switchStorageToMailbox, and the
xidachen 2016/06/14 18:09:40 Done.
+{
+ m_mailbox.textureSize = WebSize(m_image->width(), m_image->height());
+ GrContext* grContext = provider->grContext();
+ if (!grContext)
+ return false;
+ grContext->flush();
+ m_image->getTexture()->textureParamsModified();
Justin Novosad 2016/06/09 20:21:29 I am pretty sure this call is unnecessary
xidachen 2016/06/10 15:36:08 Done.
+ 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);
+ RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&m_mailbox.name[0], sizeof(m_mailbox.name)));
Justin Novosad 2016/06/09 20:21:29 No need for this. consumeTextureMailbox gets all i
xidachen 2016/06/10 15:36:08 Done.
+ m_image->getTexture()->setCustomData(mailboxNameData.get());
+ 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);
Justin Novosad 2016/06/09 20:21:29 You should discard m_image here IMHO, to make sure
xidachen 2016/06/10 15:36:08 I am a little confused. In the code path of imageF
Justin Novosad 2016/06/10 17:50:40 Right, in that case you should capture a local ref
+ return true;
+}
+
+PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame(WebGraphicsContext3DProvider* contextProvider)
+{
xidachen 2016/06/09 15:09:53 The reason I put a lot of if statement here is tha
Justin Novosad 2016/06/09 20:21:29 +1 this it is very readable.
+ if (m_image) {
+ // If the SkImage is not texture-backed
+ if (!m_image->isTextureBacked())
+ return m_image;
+ // SkImage is texture-backed, but no mailbox exists. virtual/gpu/ cases.
+ if (!hasMailbox())
Justin Novosad 2016/06/09 20:21:29 This does not seem correct to me. If you have an i
xidachen 2016/06/10 15:36:08 We actually have a layout test for that: fast/canv
Justin Novosad 2016/06/10 17:50:40 Would be worth investigating what happens to the o
+ return m_image;
+ // Has mailbox, but contextProvider is null (2D).
+ if (!contextProvider)
+ return m_image;
+ // 3D context, consume mailbox, prepare a new mailbox.
+ consumeTextureMailbox(contextProvider);
+ if (prepareMailboxForSkImage(contextProvider))
+ return nullptr;
+ return m_image;
+ }
+ // No mailbox, return null;
+ if (!hasMailbox())
+ return m_image;
Justin Novosad 2016/06/09 20:21:29 might as well make this nullptr
xidachen 2016/06/10 15:36:08 Done.
+ // Has mailbox, consume mailbox, prepare a new mailbox if contextProvider is not null (3D).
+ if (!contextProvider) {
+ DCHECK(isMainThread());
+ // TODO(xidachen): make this work on a worker thread.
+ OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+ consumeTextureMailbox(provider.get());
+ } else {
+ consumeTextureMailbox(contextProvider);
+ if (prepareMailboxForSkImage(contextProvider))
+ return nullptr;
+ }
return m_image;
}

Powered by Google App Engine
This is Rietveld 408576698