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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp

Issue 2455983005: Refactor AcceleratedStaticBitmapImage (Closed)
Patch Set: rebase Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/AcceleratedStaticBitmapImage.h" 5 #include "platform/graphics/AcceleratedStaticBitmapImage.h"
6 6
7 #include "gpu/command_buffer/client/gles2_interface.h" 7 #include "gpu/command_buffer/client/gles2_interface.h"
8 #include "gpu/command_buffer/common/sync_token.h" 8 #include "gpu/command_buffer/common/sync_token.h"
9 #include "platform/CrossThreadFunctional.h" 9 #include "platform/graphics/MailboxTextureHolder.h"
10 #include "platform/WebTaskRunner.h" 10 #include "platform/graphics/SkiaTextureHolder.h"
11 #include "platform/graphics/StaticBitmapImage.h"
12 #include "platform/graphics/gpu/SharedGpuContext.h" 11 #include "platform/graphics/gpu/SharedGpuContext.h"
13 #include "platform/graphics/skia/SkiaUtils.h" 12 #include "platform/graphics/skia/SkiaUtils.h"
14 #include "public/platform/Platform.h" 13 #include "public/platform/Platform.h"
15 #include "public/platform/WebGraphicsContext3DProvider.h" 14 #include "public/platform/WebGraphicsContext3DProvider.h"
16 #include "skia/ext/texture_handle.h"
17 #include "third_party/skia/include/core/SkImage.h" 15 #include "third_party/skia/include/core/SkImage.h"
18 #include "third_party/skia/include/gpu/GrContext.h"
19 #include "wtf/PtrUtil.h" 16 #include "wtf/PtrUtil.h"
20 17
21 #include <memory> 18 #include <memory>
22 #include <utility> 19 #include <utility>
23 20
24 namespace blink { 21 namespace blink {
25 22
26 PassRefPtr<AcceleratedStaticBitmapImage> 23 PassRefPtr<AcceleratedStaticBitmapImage>
27 AcceleratedStaticBitmapImage::createFromSharedContextImage( 24 AcceleratedStaticBitmapImage::createFromSharedContextImage(
28 sk_sp<SkImage> image) { 25 sk_sp<SkImage> image) {
29 return adoptRef(new AcceleratedStaticBitmapImage(std::move(image))); 26 return adoptRef(new AcceleratedStaticBitmapImage(std::move(image)));
30 } 27 }
31 28
32 PassRefPtr<AcceleratedStaticBitmapImage> 29 PassRefPtr<AcceleratedStaticBitmapImage>
33 AcceleratedStaticBitmapImage::createFromWebGLContextImage( 30 AcceleratedStaticBitmapImage::createFromWebGLContextImage(
34 sk_sp<SkImage> image,
35 const gpu::Mailbox& mailbox, 31 const gpu::Mailbox& mailbox,
36 const gpu::SyncToken& syncToken) { 32 const gpu::SyncToken& syncToken,
37 return adoptRef( 33 unsigned textureId,
38 new AcceleratedStaticBitmapImage(std::move(image), mailbox, syncToken)); 34 WeakPtr<DrawingBuffer> drawingBuffer,
35 IntSize mailboxSize) {
36 return adoptRef(new AcceleratedStaticBitmapImage(
37 mailbox, syncToken, textureId, drawingBuffer, mailboxSize));
39 } 38 }
40 39
41 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image) 40 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
42 : StaticBitmapImage(std::move(image)), 41 sk_sp<SkImage> image) {
43 m_sharedContextId(SharedGpuContext::contextId()) { 42 m_textureHolder = wrapUnique(new SkiaTextureHolder(std::move(image)));
44 m_threadChecker.DetachFromThread(); 43 m_threadChecker.DetachFromThread();
45 } 44 }
46 45
47 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage( 46 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(
48 sk_sp<SkImage> image,
49 const gpu::Mailbox& mailbox, 47 const gpu::Mailbox& mailbox,
50 const gpu::SyncToken& syncToken) 48 const gpu::SyncToken& syncToken,
51 : StaticBitmapImage(std::move(image)), 49 unsigned textureId,
52 m_sharedContextId(SharedGpuContext::kNoSharedContext), 50 WeakPtr<DrawingBuffer> drawingBuffer,
53 m_hasMailbox(true), 51 IntSize mailboxSize) {
54 m_mailbox(mailbox), 52 m_textureHolder = wrapUnique(new MailboxTextureHolder(
55 m_syncToken(syncToken) { 53 mailbox, syncToken, textureId, drawingBuffer, mailboxSize));
56 m_threadChecker.DetachFromThread(); 54 m_threadChecker.DetachFromThread();
57
58 // Note: In this case, m_image is not usable directly because it is not in the
59 // shared context. It is just used to hold a reference to the texture object
60 // in the origin context until the mailbox can be consumed.
61 } 55 }
62 56
63 AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() { 57 AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() {}
64 // Avoid leaking mailboxes in cases where the texture gets recycled by skia. 58
65 if (m_hasMailbox && SharedGpuContext::isValid()) 59 IntSize AcceleratedStaticBitmapImage::size() const {
66 SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, 60 return m_textureHolder->size();
67 m_mailbox.name); 61 }
68 releaseImageThreadSafe(); 62
63 void AcceleratedStaticBitmapImage::updateSyncToken(gpu::SyncToken syncToken) {
64 m_textureHolder->updateSyncToken(syncToken);
69 } 65 }
70 66
71 void AcceleratedStaticBitmapImage::copyToTexture( 67 void AcceleratedStaticBitmapImage::copyToTexture(
72 WebGraphicsContext3DProvider* destProvider, 68 WebGraphicsContext3DProvider* destProvider,
73 GLuint destTextureId, 69 GLuint destTextureId,
74 GLenum internalFormat, 70 GLenum internalFormat,
75 GLenum destType, 71 GLenum destType,
76 bool flipY) { 72 bool flipY) {
77 checkThread(); 73 checkThread();
78 if (!isValid()) 74 if (!isValid())
79 return; 75 return;
80 // |destProvider| may not be the same context as the one used for |m_image|, 76 // |destProvider| may not be the same context as the one used for |m_image|,
81 // so we use a mailbox to generate a texture id for |destProvider| to access. 77 // so we use a mailbox to generate a texture id for |destProvider| to access.
82 ensureMailbox(); 78 ensureMailbox();
83 79
84 // Get a texture id that |destProvider| knows about and copy from it. 80 // Get a texture id that |destProvider| knows about and copy from it.
85 gpu::gles2::GLES2Interface* destGL = destProvider->contextGL(); 81 gpu::gles2::GLES2Interface* destGL = destProvider->contextGL();
86 destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); 82 destGL->WaitSyncTokenCHROMIUM(m_textureHolder->syncToken().GetData());
87 GLuint sourceTextureId = 83 GLuint sourceTextureId = destGL->CreateAndConsumeTextureCHROMIUM(
88 destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); 84 GL_TEXTURE_2D, m_textureHolder->mailbox().name);
89 destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, 85 destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat,
90 destType, flipY, false, false); 86 destType, flipY, false, false);
91 // This drops the |destGL| context's reference on our |m_mailbox|, but it's 87 // This drops the |destGL| context's reference on our |m_mailbox|, but it's
92 // still held alive by our SkImage. 88 // still held alive by our SkImage.
93 destGL->DeleteTextures(1, &sourceTextureId); 89 destGL->DeleteTextures(1, &sourceTextureId);
94 } 90 }
95 91
96 sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() { 92 sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() {
97 checkThread(); 93 checkThread();
98 if (!isValid()) 94 if (!isValid())
99 return nullptr; 95 return nullptr;
100 createImageFromMailboxIfNeeded(); 96 createImageFromMailboxIfNeeded();
101 return m_image; 97 return m_textureHolder->skImage();
102 } 98 }
103 99
104 void AcceleratedStaticBitmapImage::draw( 100 void AcceleratedStaticBitmapImage::draw(SkCanvas* canvas,
105 SkCanvas* canvas, 101 const SkPaint& paint,
106 const SkPaint& paint, 102 const FloatRect& dstRect,
107 const FloatRect& dstRect, 103 const FloatRect& srcRect,
108 const FloatRect& srcRect, 104 RespectImageOrientationEnum,
109 RespectImageOrientationEnum respectImageOrientation, 105 ImageClampingMode imageClampingMode) {
110 ImageClampingMode imageClampingMode) {
111 checkThread(); 106 checkThread();
112 if (!isValid()) 107 if (!isValid())
113 return; 108 return;
114 createImageFromMailboxIfNeeded(); 109 createImageFromMailboxIfNeeded();
115 StaticBitmapImage::draw(canvas, paint, dstRect, srcRect, 110 sk_sp<SkImage> image = m_textureHolder->skImage();
116 respectImageOrientation, imageClampingMode); 111 StaticBitmapImage::drawHelper(canvas, paint, dstRect, srcRect,
112 imageClampingMode, image);
117 } 113 }
118 114
119 bool AcceleratedStaticBitmapImage::isValid() { 115 bool AcceleratedStaticBitmapImage::isValid() {
120 if (!m_image) 116 if (!m_textureHolder)
121 return false; 117 return false;
122 if (!SharedGpuContext::isValid()) 118 if (!SharedGpuContext::isValid())
123 return false; // Gpu context was lost 119 return false; // Gpu context was lost
124 if (imageBelongsToSharedContext() && 120 unsigned sharedContextId = m_textureHolder->sharedContextId();
125 m_sharedContextId != SharedGpuContext::contextId()) { 121 if (sharedContextId != SharedGpuContext::kNoSharedContext &&
122 sharedContextId != SharedGpuContext::contextId()) {
126 // Gpu context was lost and restored since the resource was created. 123 // Gpu context was lost and restored since the resource was created.
127 return false; 124 return false;
128 } 125 }
129 return true; 126 return true;
130 } 127 }
131 128
132 bool AcceleratedStaticBitmapImage::imageBelongsToSharedContext() {
133 return m_sharedContextId != SharedGpuContext::kNoSharedContext;
134 }
135
136 void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded() { 129 void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded() {
137 if (imageBelongsToSharedContext()) 130 if (m_textureHolder->sharedContextId() != SharedGpuContext::kNoSharedContext)
138 return; 131 return;
139 DCHECK(m_hasMailbox); 132 if (m_textureHolder->isSkiaTextureHolder())
140 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); 133 return;
141 GrContext* sharedGrContext = SharedGpuContext::gr(); 134 m_textureHolder =
142 DCHECK(sharedGL && 135 wrapUnique(new SkiaTextureHolder(std::move(m_textureHolder)));
143 sharedGrContext); // context isValid already checked in callers
144
145 sharedGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData());
146 GLuint sharedContextTextureId =
147 sharedGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
148 GrGLTextureInfo textureInfo;
149 textureInfo.fTarget = GL_TEXTURE_2D;
150 textureInfo.fID = sharedContextTextureId;
151 GrBackendTextureDesc backendTexture;
152 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
153 backendTexture.fWidth = size().width();
154 backendTexture.fHeight = size().height();
155 backendTexture.fConfig = kSkia8888_GrPixelConfig;
156 backendTexture.fTextureHandle =
157 skia::GrGLTextureInfoToGrBackendObject(textureInfo);
158
159 sk_sp<SkImage> newImage =
160 SkImage::MakeFromAdoptedTexture(sharedGrContext, backendTexture);
161 releaseImageThreadSafe();
162 m_image = newImage;
163
164 m_sharedContextId = SharedGpuContext::contextId();
165 } 136 }
166 137
167 void AcceleratedStaticBitmapImage::ensureMailbox() { 138 void AcceleratedStaticBitmapImage::ensureMailbox() {
168 if (m_hasMailbox) 139 if (m_textureHolder->isMailboxTextureHolder())
169 return; 140 return;
170 141
171 DCHECK(m_image); 142 m_textureHolder =
172 143 wrapUnique(new MailboxTextureHolder(std::move(m_textureHolder)));
173 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
174 GrContext* sharedGrContext = SharedGpuContext::gr();
175 if (!sharedGrContext) {
176 // Can happen if the context is lost. The SkImage won't be any good now
177 // anyway.
178 return;
179 }
180 GLuint imageTextureId =
181 skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true))
182 ->fID;
183 sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId);
184
185 sharedGL->GenMailboxCHROMIUM(m_mailbox.name);
186 sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
187 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM();
188 sharedGL->Flush();
189 sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData());
190
191 sharedGL->BindTexture(GL_TEXTURE_2D, 0);
192 // We changed bound textures in this function, so reset the GrContext.
193 sharedGrContext->resetContext(kTextureBinding_GrGLBackendState);
194
195 m_hasMailbox = true;
196 } 144 }
197 145
198 void AcceleratedStaticBitmapImage::transfer() { 146 void AcceleratedStaticBitmapImage::transfer() {
199 checkThread(); 147 checkThread();
200 ensureMailbox(); 148 ensureMailbox();
201 m_sharedContextId = SharedGpuContext::kNoSharedContext; 149 m_textureHolder->deleteTexture();
xidachen 2016/11/04 17:23:06 junov@: Please take a look at this change here. I
202 // If |m_imageThread| is set, it means that the image has been consumed on the 150 // If |m_imageThreadTaskRunner| in SkiaTextureHolder is set, it means that
203 // current thread, which may happen when we have chained transfers. When that 151 // the |m_image| in that class has been consumed on the current thread, which
204 // is the case, we must not reset |m_imageThread|, so we ensure that 152 // may happen when we have chained transfers. When that is the case, we must
205 // releaseImage() is called on the right thread. 153 // not reset |m_imageThreadTaskRunner|, so we ensure that releaseImage() is
206 if (!m_imageThread) 154 // called on the right thread.
207 m_imageThread = Platform::current()->currentThread(); 155 if (!m_textureHolder->imageThread()) {
156 WebThread* currentThread = Platform::current()->currentThread();
157 m_textureHolder->setImageThread(currentThread);
158 m_textureHolder->setImageThreadTaskRunner(
159 currentThread->getWebTaskRunner()->clone());
160 }
208 m_detachThreadAtNextCheck = true; 161 m_detachThreadAtNextCheck = true;
209 } 162 }
210 163
164 bool AcceleratedStaticBitmapImage::currentFrameKnownToBeOpaque(
165 MetadataMode metadataMode) {
166 return m_textureHolder->currentFrameKnownToBeOpaque(metadataMode);
167 }
168
211 void AcceleratedStaticBitmapImage::checkThread() { 169 void AcceleratedStaticBitmapImage::checkThread() {
212 if (m_detachThreadAtNextCheck) { 170 if (m_detachThreadAtNextCheck) {
213 m_threadChecker.DetachFromThread(); 171 m_threadChecker.DetachFromThread();
214 m_detachThreadAtNextCheck = false; 172 m_detachThreadAtNextCheck = false;
215 } 173 }
216 CHECK(m_threadChecker.CalledOnValidThread()); 174 CHECK(m_threadChecker.CalledOnValidThread());
217 } 175 }
218 176
219 void releaseImage(sk_sp<SkImage>&& image,
220 std::unique_ptr<gpu::SyncToken>&& syncToken) {
221 if (SharedGpuContext::isValid() && syncToken->HasData())
222 SharedGpuContext::gl()->WaitSyncTokenCHROMIUM(syncToken->GetData());
223 image.reset();
224 }
225
226 void AcceleratedStaticBitmapImage::releaseImageThreadSafe() {
227 // If m_image belongs to a GrContext that is on another thread, it
228 // must be released on that thread.
229 if (m_imageThread && m_image &&
230 m_imageThread != Platform::current()->currentThread() &&
231 SharedGpuContext::isValid()) {
232 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
233 std::unique_ptr<gpu::SyncToken> releaseSyncToken(new gpu::SyncToken);
234 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM();
235 sharedGL->Flush();
236 sharedGL->GenSyncTokenCHROMIUM(fenceSync, releaseSyncToken->GetData());
237 m_imageThread->getWebTaskRunner()->postTask(
238 BLINK_FROM_HERE,
239 crossThreadBind(&releaseImage, passed(std::move(m_image)),
240 passed(std::move(releaseSyncToken))));
241 }
242 m_image = nullptr;
243 m_imageThread = nullptr;
244 }
245
246 } // namespace blink 177 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698