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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/graphics/StaticBitmapImage.h" 5 #include "platform/graphics/StaticBitmapImage.h"
6 6
7 #include "gpu/command_buffer/client/gles2_interface.h" 7 #include "gpu/command_buffer/client/gles2_interface.h"
8 #include "platform/graphics/GraphicsContext.h" 8 #include "platform/graphics/GraphicsContext.h"
9 #include "platform/graphics/ImageObserver.h" 9 #include "platform/graphics/ImageObserver.h"
10 #include "public/platform/Platform.h" 10 #include "public/platform/Platform.h"
11 #include "public/platform/WebGraphicsContext3DProvider.h" 11 #include "public/platform/WebGraphicsContext3DProvider.h"
12 #include "skia/ext/texture_handle.h" 12 #include "skia/ext/texture_handle.h"
13 #include "third_party/skia/include/core/SkCanvas.h" 13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkImage.h" 14 #include "third_party/skia/include/core/SkImage.h"
15 #include "third_party/skia/include/core/SkPaint.h" 15 #include "third_party/skia/include/core/SkPaint.h"
16 #include "third_party/skia/include/core/SkShader.h" 16 #include "third_party/skia/include/core/SkShader.h"
17 #include "third_party/skia/include/gpu/GrContext.h"
17 18
18 namespace blink { 19 namespace blink {
19 20
20 PassRefPtr<StaticBitmapImage> StaticBitmapImage::create(PassRefPtr<SkImage> imag e) 21 PassRefPtr<StaticBitmapImage> StaticBitmapImage::create(PassRefPtr<SkImage> imag e)
21 { 22 {
22 if (!image) 23 if (!image)
23 return nullptr; 24 return nullptr;
24 return adoptRef(new StaticBitmapImage(image)); 25 return adoptRef(new StaticBitmapImage(image));
25 } 26 }
26 27
27 PassRefPtr<StaticBitmapImage> StaticBitmapImage::create(WebExternalTextureMailbo x& mailbox) 28 PassRefPtr<StaticBitmapImage> StaticBitmapImage::create(WebExternalTextureMailbo x& mailbox)
28 { 29 {
29 return adoptRef(new StaticBitmapImage(mailbox)); 30 return adoptRef(new StaticBitmapImage(mailbox));
30 } 31 }
31 32
32 StaticBitmapImage::StaticBitmapImage(PassRefPtr<SkImage> image) : m_image(image) 33 StaticBitmapImage::StaticBitmapImage(PassRefPtr<SkImage> image) : m_image(image)
33 { 34 {
34 ASSERT(m_image); 35 ASSERT(m_image);
35 } 36 }
36 37
37 StaticBitmapImage::StaticBitmapImage(WebExternalTextureMailbox& mailbox) : m_mai lbox(mailbox) 38 StaticBitmapImage::StaticBitmapImage(WebExternalTextureMailbox& mailbox) : m_mai lbox(mailbox)
38 { 39 {
39 } 40 }
40 41
41 StaticBitmapImage::~StaticBitmapImage() { } 42 StaticBitmapImage::~StaticBitmapImage() { }
42 43
43 IntSize StaticBitmapImage::size() const 44 IntSize StaticBitmapImage::size() const
44 { 45 {
46 if (!m_image)
47 return IntSize(m_mailbox.textureSize.width, m_mailbox.textureSize.height );
45 return IntSize(m_image->width(), m_image->height()); 48 return IntSize(m_image->width(), m_image->height());
46 } 49 }
47 50
51 bool StaticBitmapImage::isTextureBacked()
52 {
53 return m_image && m_image->isTextureBacked();
54 }
55
48 bool StaticBitmapImage::currentFrameKnownToBeOpaque(MetadataMode) 56 bool StaticBitmapImage::currentFrameKnownToBeOpaque(MetadataMode)
49 { 57 {
50 return m_image->isOpaque(); 58 return m_image->isOpaque();
51 } 59 }
52 60
53 void StaticBitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const Float Rect& dstRect, 61 void StaticBitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const Float Rect& dstRect,
54 const FloatRect& srcRect, RespectImageOrientationEnum, ImageClampingMode cla mpMode) 62 const FloatRect& srcRect, RespectImageOrientationEnum, ImageClampingMode cla mpMode)
55 { 63 {
56 FloatRect adjustedSrcRect = srcRect; 64 FloatRect adjustedSrcRect = srcRect;
57 adjustedSrcRect.intersect(SkRect::Make(m_image->bounds())); 65 adjustedSrcRect.intersect(SkRect::Make(m_image->bounds()));
58 66
59 if (dstRect.isEmpty() || adjustedSrcRect.isEmpty()) 67 if (dstRect.isEmpty() || adjustedSrcRect.isEmpty())
60 return; // Nothing to draw. 68 return; // Nothing to draw.
61 69
62 canvas->drawImageRect(m_image.get(), adjustedSrcRect, dstRect, &paint, 70 canvas->drawImageRect(m_image.get(), adjustedSrcRect, dstRect, &paint,
63 WebCoreClampingModeToSkiaRectConstraint(clampMode)); 71 WebCoreClampingModeToSkiaRectConstraint(clampMode));
64 72
65 if (ImageObserver* observer = getImageObserver()) 73 if (ImageObserver* observer = getImageObserver())
66 observer->didDraw(this); 74 observer->didDraw(this);
67 } 75 }
68 76
69 PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame() 77 void StaticBitmapImage::consumeTextureMailbox(WebGraphicsContext3DProvider* prov ider)
70 { 78 {
71 if (m_image)
72 return m_image;
73 DCHECK(isMainThread());
74 // In the place when we consume an ImageBitmap that is gpu texture backed,
75 // create a new SkImage from that texture.
76 // TODO(xidachen): make this work on a worker thread.
77 OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current() ->createSharedOffscreenGraphicsContext3DProvider());
78 if (!provider) 79 if (!provider)
79 return nullptr; 80 return;
80 GrContext* grContext = provider->grContext(); 81 GrContext* grContext = provider->grContext();
81 if (!grContext) 82 if (!grContext)
82 return nullptr; 83 return;
83 gpu::gles2::GLES2Interface* gl = provider->contextGL(); 84 gpu::gles2::GLES2Interface* gl = provider->contextGL();
84 if (!gl) 85 if (!gl)
85 return nullptr; 86 return;
86 gl->WaitSyncTokenCHROMIUM(m_mailbox.syncToken); 87 gl->WaitSyncTokenCHROMIUM(m_mailbox.syncToken);
87 GLuint textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mail box.name); 88 m_textureId = gl->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.n ame);
88 GrGLTextureInfo textureInfo; 89 GrGLTextureInfo textureInfo;
89 textureInfo.fTarget = GL_TEXTURE_2D; 90 textureInfo.fTarget = GL_TEXTURE_2D;
90 textureInfo.fID = textureId; 91 textureInfo.fID = m_textureId;
91 GrBackendTextureDesc backendTexture; 92 GrBackendTextureDesc backendTexture;
92 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin; 93 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
93 backendTexture.fWidth = m_mailbox.textureSize.width; 94 backendTexture.fWidth = m_mailbox.textureSize.width;
94 backendTexture.fHeight = m_mailbox.textureSize.height; 95 backendTexture.fHeight = m_mailbox.textureSize.height;
95 backendTexture.fConfig = kSkia8888_GrPixelConfig; 96 backendTexture.fConfig = kSkia8888_GrPixelConfig;
96 backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textu reInfo); 97 backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textu reInfo);
97 sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendT exture); 98 sk_sp<SkImage> skImage = SkImage::MakeFromAdoptedTexture(grContext, backendT exture);
98 m_image = fromSkSp(skImage); 99 m_image = fromSkSp(skImage);
100 }
101
102 void StaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* provider, GL uint destinationTexture, GLenum internalFormat, GLenum destType)
103 {
104 gpu::gles2::GLES2Interface* gl = provider->contextGL();
105 if (!gl)
106 return;
107 gl->CopyTextureCHROMIUM(m_textureId, destinationTexture, internalFormat, des tType, false, false, false);
108 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
109 GLbyte syncToken[24];
110 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken);
111 }
112
113 bool StaticBitmapImage::prepareMailboxForSkImage(WebGraphicsContext3DProvider* p rovider)
Justin Novosad 2016/06/10 17:50:40 Could we call this switchStorageToMailbox, and the
xidachen 2016/06/14 18:09:40 Done.
114 {
115 m_mailbox.textureSize = WebSize(m_image->width(), m_image->height());
116 GrContext* grContext = provider->grContext();
117 if (!grContext)
118 return false;
119 grContext->flush();
120 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.
121 m_mailbox.textureTarget = GL_TEXTURE_2D;
122 gpu::gles2::GLES2Interface* gl = provider->contextGL();
123 if (!gl)
124 return false;
125 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextur eHandle(true))->fID;
126 gl->BindTexture(GL_TEXTURE_2D, textureID);
127
128 gl->GenMailboxCHROMIUM(m_mailbox.name);
129 RefPtr<SkData> mailboxNameData = adoptRef(SkData::NewWithCopy(&m_mailbox.nam e[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.
130 m_image->getTexture()->setCustomData(mailboxNameData.get());
131 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
132 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
133 gl->Flush();
134 gl->GenSyncTokenCHROMIUM(fenceSync, m_mailbox.syncToken);
135 m_mailbox.validSyncToken = true;
136 gl->BindTexture(GL_TEXTURE_2D, 0);
137 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
138 return true;
139 }
140
141 PassRefPtr<SkImage> StaticBitmapImage::imageForCurrentFrame(WebGraphicsContext3D Provider* contextProvider)
142 {
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.
143 if (m_image) {
144 // If the SkImage is not texture-backed
145 if (!m_image->isTextureBacked())
146 return m_image;
147 // SkImage is texture-backed, but no mailbox exists. virtual/gpu/ cases.
148 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
149 return m_image;
150 // Has mailbox, but contextProvider is null (2D).
151 if (!contextProvider)
152 return m_image;
153 // 3D context, consume mailbox, prepare a new mailbox.
154 consumeTextureMailbox(contextProvider);
155 if (prepareMailboxForSkImage(contextProvider))
156 return nullptr;
157 return m_image;
158 }
159 // No mailbox, return null;
160 if (!hasMailbox())
161 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.
162 // Has mailbox, consume mailbox, prepare a new mailbox if contextProvider is not null (3D).
163 if (!contextProvider) {
164 DCHECK(isMainThread());
165 // TODO(xidachen): make this work on a worker thread.
166 OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::curre nt()->createSharedOffscreenGraphicsContext3DProvider());
167 consumeTextureMailbox(provider.get());
168 } else {
169 consumeTextureMailbox(contextProvider);
170 if (prepareMailboxForSkImage(contextProvider))
171 return nullptr;
172 }
99 return m_image; 173 return m_image;
100 } 174 }
101 175
102 } // namespace blink 176 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698