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

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

Issue 2323573002: Revert of Allow canvases to be GPU-accelerated in Workers (Closed)
Patch Set: Created 4 years, 3 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 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"
10 #include "platform/graphics/StaticBitmapImage.h" 9 #include "platform/graphics/StaticBitmapImage.h"
11 #include "platform/graphics/gpu/SharedGpuContext.h"
12 #include "platform/graphics/skia/SkiaUtils.h" 10 #include "platform/graphics/skia/SkiaUtils.h"
13 #include "public/platform/Platform.h" 11 #include "public/platform/Platform.h"
14 #include "public/platform/WebGraphicsContext3DProvider.h" 12 #include "public/platform/WebGraphicsContext3DProvider.h"
15 #include "public/platform/WebTaskRunner.h"
16 #include "skia/ext/texture_handle.h" 13 #include "skia/ext/texture_handle.h"
17 #include "third_party/skia/include/core/SkImage.h" 14 #include "third_party/skia/include/core/SkImage.h"
18 #include "third_party/skia/include/gpu/GrContext.h" 15 #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> AcceleratedStaticBitmapImage::createFro mSharedContextImage(sk_sp<SkImage> image) 23 PassRefPtr<AcceleratedStaticBitmapImage> AcceleratedStaticBitmapImage::create(sk _sp<SkImage> image)
27 { 24 {
28 return adoptRef(new AcceleratedStaticBitmapImage(std::move(image))); 25 return adoptRef(new AcceleratedStaticBitmapImage(std::move(image)));
29 } 26 }
30 27
31 PassRefPtr<AcceleratedStaticBitmapImage> AcceleratedStaticBitmapImage::createFro mWebGLContextImage(sk_sp<SkImage> image, const gpu::Mailbox& mailbox, const gpu: :SyncToken& syncToken) 28 PassRefPtr<AcceleratedStaticBitmapImage> AcceleratedStaticBitmapImage::create(sk _sp<SkImage> image, sk_sp<GrContext> grContext, const gpu::Mailbox& mailbox, con st gpu::SyncToken& syncToken)
32 { 29 {
33 return adoptRef(new AcceleratedStaticBitmapImage(std::move(image), mailbox, syncToken)); 30 return adoptRef(new AcceleratedStaticBitmapImage(std::move(image), std::move (grContext), mailbox, syncToken));
34 } 31 }
35 32
36 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image) 33 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image)
37 : StaticBitmapImage(std::move(image)) 34 : StaticBitmapImage(std::move(image))
38 , m_sharedContextId(SharedGpuContext::contextId()) 35 , m_imageIsForSharedMainThreadContext(true)
39 { 36 {
40 m_threadChecker.DetachFromThread();
41 } 37 }
42 38
43 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image, const gpu::Mailbox& mailbox, const gpu::SyncToken& syncToken) 39 AcceleratedStaticBitmapImage::AcceleratedStaticBitmapImage(sk_sp<SkImage> image, sk_sp<GrContext> grContext, const gpu::Mailbox& mailbox, const gpu::SyncToken& syncToken)
44 : StaticBitmapImage(std::move(image)) 40 : StaticBitmapImage(std::move(image))
45 , m_sharedContextId(SharedGpuContext::kNoSharedContext) 41 , m_imageIsForSharedMainThreadContext(false) // TODO(danakj): Could be true though, caller would know.
42 , m_grContext(std::move(grContext))
46 , m_hasMailbox(true) 43 , m_hasMailbox(true)
47 , m_mailbox(mailbox) 44 , m_mailbox(mailbox)
48 , m_syncToken(syncToken) 45 , m_syncToken(syncToken)
49 { 46 {
50 m_threadChecker.DetachFromThread(); 47 DCHECK(m_grContext);
51
52 // Note: In this case, m_image is not usable directly because it is not in t he shared context.
53 // It is just used to hold a reference to the texture object in the origin c ontext until the
54 // mailbox can be consumed.
55 } 48 }
56 49
57 AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() 50 AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() = default;
58 {
59 // Avoid leaking mailboxes in cases where the texture gets recycled by skia.
60 if (m_hasMailbox && SharedGpuContext::isValid())
61 SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, m _mailbox.name);
62 releaseImageThreadSafe();
63 }
64 51
65 void AcceleratedStaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* d estProvider, GLuint destTextureId, GLenum internalFormat, GLenum destType, bool flipY) 52 void AcceleratedStaticBitmapImage::copyToTexture(WebGraphicsContext3DProvider* d estProvider, GLuint destTextureId, GLenum internalFormat, GLenum destType, bool flipY)
66 { 53 {
67 checkThread();
68 if (!isValid())
69 return;
70 // |destProvider| may not be the same context as the one used for |m_image| so we use a mailbox to 54 // |destProvider| may not be the same context as the one used for |m_image| so we use a mailbox to
71 // generate a texture id for |destProvider| to access. 55 // generate a texture id for |destProvider| to access.
72 ensureMailbox(); 56 ensureMailbox();
73 57
74 // Get a texture id that |destProvider| knows about and copy from it. 58 // Get a texture id that |destProvider| knows about and copy from it.
75 gpu::gles2::GLES2Interface* destGL = destProvider->contextGL(); 59 gpu::gles2::GLES2Interface* destGL = destProvider->contextGL();
76 destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); 60 destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData());
77 GLuint sourceTextureId = destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_ 2D, m_mailbox.name); 61 GLuint sourceTextureId = destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_ 2D, m_mailbox.name);
78 destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, destType, flipY, false, false); 62 destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, destType, flipY, false, false);
79 // This drops the |destGL| context's reference on our |m_mailbox|, but it's still held alive by our SkImage. 63 // This drops the |destGL| context's reference on our |m_mailbox|, but it's still held alive by our SkImage.
80 destGL->DeleteTextures(1, &sourceTextureId); 64 destGL->DeleteTextures(1, &sourceTextureId);
81 } 65 }
82 66
83 sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() 67 sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame()
84 { 68 {
85 checkThread(); 69 // This must return an SkImage that can be used with the shared main thread context. If |m_image| satisfies that, we are done.
86 if (!isValid()) 70 if (m_imageIsForSharedMainThreadContext)
87 return nullptr; 71 return m_image;
88 createImageFromMailboxIfNeeded();
89 return m_image;
90 }
91 72
92 void AcceleratedStaticBitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, RespectImageOrientationEnum respectImageOrientation, ImageClampingMode imageClampingMode) 73 // TODO(xidachen): make this work on a worker thread.
93 { 74 DCHECK(isMainThread());
94 checkThread();
95 if (!isValid())
96 return;
97 createImageFromMailboxIfNeeded();
98 StaticBitmapImage::draw(canvas, paint, dstRect, srcRect, respectImageOrienta tion, imageClampingMode);
99 }
100 75
101 bool AcceleratedStaticBitmapImage::isValid() 76 // If the SkImage came from any other context than the shared main thread on e, we expect to be given a mailbox at construction. We
102 { 77 // use the mailbox to generate a texture id for the shared main thread conte xt to use.
103 if (!m_image) 78 DCHECK(m_hasMailbox);
104 return false;
105 if (!SharedGpuContext::isValid())
106 return false; // Gpu context was lost
107 if (imageBelongsToSharedContext() && m_sharedContextId != SharedGpuContext:: contextId())
108 return false; // Gpu context was lost an restored since resource was cre ated
109 return true;
110 }
111 79
112 bool AcceleratedStaticBitmapImage::imageBelongsToSharedContext() 80 auto sharedMainThreadContextProvider = wrapUnique(Platform::current()->creat eSharedOffscreenGraphicsContext3DProvider());
113 { 81 gpu::gles2::GLES2Interface* sharedGL = sharedMainThreadContextProvider->cont extGL();
114 return m_sharedContextId != SharedGpuContext::kNoSharedContext; 82 GrContext* sharedGrContext = sharedMainThreadContextProvider->grContext();
115 } 83 if (!sharedGrContext)
116 84 return nullptr; // Can happen if the context is lost, the SkImage won't be any good now anyway.
117 void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded()
118 {
119 if (imageBelongsToSharedContext())
120 return;
121 DCHECK(m_hasMailbox);
122 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
123 GrContext* sharedGrContext = SharedGpuContext::gr();
124 DCHECK(sharedGL && sharedGrContext); // context isValid already checked in c allers
125 85
126 sharedGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); 86 sharedGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData());
127 GLuint sharedContextTextureId = sharedGL->CreateAndConsumeTextureCHROMIUM(GL _TEXTURE_2D, m_mailbox.name); 87 GLuint sharedContextTextureId = sharedGL->CreateAndConsumeTextureCHROMIUM(GL _TEXTURE_2D, m_mailbox.name);
88
128 GrGLTextureInfo textureInfo; 89 GrGLTextureInfo textureInfo;
129 textureInfo.fTarget = GL_TEXTURE_2D; 90 textureInfo.fTarget = GL_TEXTURE_2D;
130 textureInfo.fID = sharedContextTextureId; 91 textureInfo.fID = sharedContextTextureId;
131 GrBackendTextureDesc backendTexture; 92 GrBackendTextureDesc backendTexture;
132 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin; 93 backendTexture.fOrigin = kBottomLeft_GrSurfaceOrigin;
133 backendTexture.fWidth = size().width(); 94 backendTexture.fWidth = size().width();
134 backendTexture.fHeight = size().height(); 95 backendTexture.fHeight = size().height();
135 backendTexture.fConfig = kSkia8888_GrPixelConfig; 96 backendTexture.fConfig = kSkia8888_GrPixelConfig;
136 backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textu reInfo); 97 backendTexture.fTextureHandle = skia::GrGLTextureInfoToGrBackendObject(textu reInfo);
137 98
138 sk_sp<SkImage> newImage = SkImage::MakeFromAdoptedTexture(sharedGrContext, b ackendTexture); 99 m_image = SkImage::MakeFromAdoptedTexture(sharedGrContext, backendTexture);
139 releaseImageThreadSafe(); 100 m_imageIsForSharedMainThreadContext = true;
140 m_image = newImage; 101 // Can drop the ref on the GrContext since m_image is now backed by a textur e from the shared main thread context.
141 102 m_grContext = nullptr;
142 m_sharedContextId = SharedGpuContext::contextId(); 103 return m_image;
143 } 104 }
144 105
145 void AcceleratedStaticBitmapImage::ensureMailbox() 106 void AcceleratedStaticBitmapImage::ensureMailbox()
146 { 107 {
147 if (m_hasMailbox) 108 if (m_hasMailbox)
148 return; 109 return;
149 110
150 DCHECK(m_image); 111 // If we weren't given a mailbox at creation, then we were given a SkImage t hat is assumed to be from the shared main thread context.
112 DCHECK(m_imageIsForSharedMainThreadContext);
113 auto sharedMainThreadContextProvider = wrapUnique(Platform::current()->creat eSharedOffscreenGraphicsContext3DProvider());
151 114
152 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); 115 gpu::gles2::GLES2Interface* sharedGL = sharedMainThreadContextProvider->cont extGL();
153 GrContext* sharedGrContext = SharedGpuContext::gr(); 116 GrContext* sharedGrContext = sharedMainThreadContextProvider->grContext();
154 if (!sharedGrContext) 117 if (!sharedGrContext)
155 return; // Can happen if the context is lost, the SkImage won't be any g ood now anyway. 118 return; // Can happen if the context is lost, the SkImage won't be any g ood now anyway.
119
156 GLuint imageTextureId = skia::GrBackendObjectToGrGLTextureInfo(m_image->getT extureHandle(true))->fID; 120 GLuint imageTextureId = skia::GrBackendObjectToGrGLTextureInfo(m_image->getT extureHandle(true))->fID;
157 sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId); 121 sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId);
158 122
159 sharedGL->GenMailboxCHROMIUM(m_mailbox.name); 123 sharedGL->GenMailboxCHROMIUM(m_mailbox.name);
160 sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); 124 sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name);
161 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); 125 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM();
162 sharedGL->Flush(); 126 sharedGL->Flush();
163 sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData()); 127 sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData());
164 128
165 sharedGL->BindTexture(GL_TEXTURE_2D, 0); 129 sharedGL->BindTexture(GL_TEXTURE_2D, 0);
166 // We changed bound textures in this function, so reset the GrContext. 130 // We changed bound textures in this function, so reset the GrContext.
167 sharedGrContext->resetContext(kTextureBinding_GrGLBackendState); 131 sharedGrContext->resetContext(kTextureBinding_GrGLBackendState);
168 132
169 m_hasMailbox = true; 133 m_hasMailbox = true;
170 } 134 }
171 135
172 void AcceleratedStaticBitmapImage::transfer()
173 {
174 checkThread();
175 ensureMailbox();
176 m_sharedContextId = SharedGpuContext::kNoSharedContext;
177 // If image thread is set, it means that the image has been consumed on the current thread,
178 // which may happen when we have chained transfers. When that is the case, w e must not
179 // reset m_imageThread to ensure that releaseImage is called on the right th read.
180 if (!m_imageThread)
181 m_imageThread = Platform::current()->currentThread();
182 m_detachThreadAtNextCheck = true;
183 }
184
185 void AcceleratedStaticBitmapImage::checkThread()
186 {
187 if (m_detachThreadAtNextCheck) {
188 m_threadChecker.DetachFromThread();
189 m_detachThreadAtNextCheck = false;
190 }
191 CHECK(m_threadChecker.CalledOnValidThread());
192 }
193
194 void releaseImage(sk_sp<SkImage>&& image, std::unique_ptr<gpu::SyncToken>&& sync Token)
195 {
196 if (SharedGpuContext::isValid() && syncToken->HasData())
197 SharedGpuContext::gl()->WaitSyncTokenCHROMIUM(syncToken->GetData());
198 image.reset();
199 }
200
201 void AcceleratedStaticBitmapImage::releaseImageThreadSafe()
202 {
203 // If m_image belongs to a GrContext that is on another thread, it
204 // must be released on that thread.
205 if (m_imageThread && m_image && m_imageThread != Platform::current()->curren tThread() && SharedGpuContext::isValid()) {
206 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
207 std::unique_ptr<gpu::SyncToken> releaseSyncToken(new gpu::SyncToken);
208 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM();
209 sharedGL->Flush();
210 sharedGL->GenSyncTokenCHROMIUM(fenceSync, releaseSyncToken->GetData());
211 m_imageThread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, crossThread Bind(&releaseImage, passed(std::move(m_image)), passed(std::move(releaseSyncToke n))));
212 }
213 m_image = nullptr;
214 m_imageThread = nullptr;
215 }
216
217 } // namespace blink 136 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698