| OLD | NEW |
| 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/CrossThreadFunctional.h" |
| 10 #include "platform/graphics/StaticBitmapImage.h" | 10 #include "platform/graphics/StaticBitmapImage.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 sk_sp<SkImage> image, | 48 sk_sp<SkImage> image, |
| 49 const gpu::Mailbox& mailbox, | 49 const gpu::Mailbox& mailbox, |
| 50 const gpu::SyncToken& syncToken) | 50 const gpu::SyncToken& syncToken) |
| 51 : StaticBitmapImage(std::move(image)), | 51 : StaticBitmapImage(std::move(image)), |
| 52 m_sharedContextId(SharedGpuContext::kNoSharedContext), | 52 m_sharedContextId(SharedGpuContext::kNoSharedContext), |
| 53 m_hasMailbox(true), | 53 m_hasMailbox(true), |
| 54 m_mailbox(mailbox), | 54 m_mailbox(mailbox), |
| 55 m_syncToken(syncToken) { | 55 m_syncToken(syncToken) { |
| 56 m_threadChecker.DetachFromThread(); | 56 m_threadChecker.DetachFromThread(); |
| 57 | 57 |
| 58 // Note: In this case, m_image is not usable directly because it is not in the
shared context. | 58 // Note: In this case, m_image is not usable directly because it is not in the |
| 59 // It is just used to hold a reference to the texture object in the origin con
text until the | 59 // shared context. It is just used to hold a reference to the texture object |
| 60 // mailbox can be consumed. | 60 // in the origin context until the mailbox can be consumed. |
| 61 } | 61 } |
| 62 | 62 |
| 63 AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() { | 63 AcceleratedStaticBitmapImage::~AcceleratedStaticBitmapImage() { |
| 64 // Avoid leaking mailboxes in cases where the texture gets recycled by skia. | 64 // Avoid leaking mailboxes in cases where the texture gets recycled by skia. |
| 65 if (m_hasMailbox && SharedGpuContext::isValid()) | 65 if (m_hasMailbox && SharedGpuContext::isValid()) |
| 66 SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, | 66 SharedGpuContext::gl()->ProduceTextureDirectCHROMIUM(0, GL_TEXTURE_2D, |
| 67 m_mailbox.name); | 67 m_mailbox.name); |
| 68 releaseImageThreadSafe(); | 68 releaseImageThreadSafe(); |
| 69 } | 69 } |
| 70 | 70 |
| 71 void AcceleratedStaticBitmapImage::copyToTexture( | 71 void AcceleratedStaticBitmapImage::copyToTexture( |
| 72 WebGraphicsContext3DProvider* destProvider, | 72 WebGraphicsContext3DProvider* destProvider, |
| 73 GLuint destTextureId, | 73 GLuint destTextureId, |
| 74 GLenum internalFormat, | 74 GLenum internalFormat, |
| 75 GLenum destType, | 75 GLenum destType, |
| 76 bool flipY) { | 76 bool flipY) { |
| 77 checkThread(); | 77 checkThread(); |
| 78 if (!isValid()) | 78 if (!isValid()) |
| 79 return; | 79 return; |
| 80 // |destProvider| may not be the same context as the one used for |m_image| so
we use a mailbox to | 80 // |destProvider| may not be the same context as the one used for |m_image|, |
| 81 // generate a texture id for |destProvider| to access. | 81 // so we use a mailbox to generate a texture id for |destProvider| to access. |
| 82 ensureMailbox(); | 82 ensureMailbox(); |
| 83 | 83 |
| 84 // Get a texture id that |destProvider| knows about and copy from it. | 84 // Get a texture id that |destProvider| knows about and copy from it. |
| 85 gpu::gles2::GLES2Interface* destGL = destProvider->contextGL(); | 85 gpu::gles2::GLES2Interface* destGL = destProvider->contextGL(); |
| 86 destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); | 86 destGL->WaitSyncTokenCHROMIUM(m_syncToken.GetData()); |
| 87 GLuint sourceTextureId = | 87 GLuint sourceTextureId = |
| 88 destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); | 88 destGL->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| 89 destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, | 89 destGL->CopyTextureCHROMIUM(sourceTextureId, destTextureId, internalFormat, |
| 90 destType, flipY, false, false); | 90 destType, flipY, false, false); |
| 91 // This drops the |destGL| context's reference on our |m_mailbox|, but it's st
ill held alive by our SkImage. | 91 // This drops the |destGL| context's reference on our |m_mailbox|, but it's |
| 92 // still held alive by our SkImage. |
| 92 destGL->DeleteTextures(1, &sourceTextureId); | 93 destGL->DeleteTextures(1, &sourceTextureId); |
| 93 } | 94 } |
| 94 | 95 |
| 95 sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() { | 96 sk_sp<SkImage> AcceleratedStaticBitmapImage::imageForCurrentFrame() { |
| 96 checkThread(); | 97 checkThread(); |
| 97 if (!isValid()) | 98 if (!isValid()) |
| 98 return nullptr; | 99 return nullptr; |
| 99 createImageFromMailboxIfNeeded(); | 100 createImageFromMailboxIfNeeded(); |
| 100 return m_image; | 101 return m_image; |
| 101 } | 102 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 114 StaticBitmapImage::draw(canvas, paint, dstRect, srcRect, | 115 StaticBitmapImage::draw(canvas, paint, dstRect, srcRect, |
| 115 respectImageOrientation, imageClampingMode); | 116 respectImageOrientation, imageClampingMode); |
| 116 } | 117 } |
| 117 | 118 |
| 118 bool AcceleratedStaticBitmapImage::isValid() { | 119 bool AcceleratedStaticBitmapImage::isValid() { |
| 119 if (!m_image) | 120 if (!m_image) |
| 120 return false; | 121 return false; |
| 121 if (!SharedGpuContext::isValid()) | 122 if (!SharedGpuContext::isValid()) |
| 122 return false; // Gpu context was lost | 123 return false; // Gpu context was lost |
| 123 if (imageBelongsToSharedContext() && | 124 if (imageBelongsToSharedContext() && |
| 124 m_sharedContextId != SharedGpuContext::contextId()) | 125 m_sharedContextId != SharedGpuContext::contextId()) { |
| 125 return false; // Gpu context was lost an restored since resource was create
d | 126 // Gpu context was lost and restored since the resource was created. |
| 127 return false; |
| 128 } |
| 126 return true; | 129 return true; |
| 127 } | 130 } |
| 128 | 131 |
| 129 bool AcceleratedStaticBitmapImage::imageBelongsToSharedContext() { | 132 bool AcceleratedStaticBitmapImage::imageBelongsToSharedContext() { |
| 130 return m_sharedContextId != SharedGpuContext::kNoSharedContext; | 133 return m_sharedContextId != SharedGpuContext::kNoSharedContext; |
| 131 } | 134 } |
| 132 | 135 |
| 133 void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded() { | 136 void AcceleratedStaticBitmapImage::createImageFromMailboxIfNeeded() { |
| 134 if (imageBelongsToSharedContext()) | 137 if (imageBelongsToSharedContext()) |
| 135 return; | 138 return; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 162 } | 165 } |
| 163 | 166 |
| 164 void AcceleratedStaticBitmapImage::ensureMailbox() { | 167 void AcceleratedStaticBitmapImage::ensureMailbox() { |
| 165 if (m_hasMailbox) | 168 if (m_hasMailbox) |
| 166 return; | 169 return; |
| 167 | 170 |
| 168 DCHECK(m_image); | 171 DCHECK(m_image); |
| 169 | 172 |
| 170 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); | 173 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); |
| 171 GrContext* sharedGrContext = SharedGpuContext::gr(); | 174 GrContext* sharedGrContext = SharedGpuContext::gr(); |
| 172 if (!sharedGrContext) | 175 if (!sharedGrContext) { |
| 173 return; // Can happen if the context is lost, the SkImage won't be any good
now anyway. | 176 // Can happen if the context is lost. The SkImage won't be any good now |
| 177 // anyway. |
| 178 return; |
| 179 } |
| 174 GLuint imageTextureId = | 180 GLuint imageTextureId = |
| 175 skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true)) | 181 skia::GrBackendObjectToGrGLTextureInfo(m_image->getTextureHandle(true)) |
| 176 ->fID; | 182 ->fID; |
| 177 sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId); | 183 sharedGL->BindTexture(GL_TEXTURE_2D, imageTextureId); |
| 178 | 184 |
| 179 sharedGL->GenMailboxCHROMIUM(m_mailbox.name); | 185 sharedGL->GenMailboxCHROMIUM(m_mailbox.name); |
| 180 sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); | 186 sharedGL->ProduceTextureCHROMIUM(GL_TEXTURE_2D, m_mailbox.name); |
| 181 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); | 187 const GLuint64 fenceSync = sharedGL->InsertFenceSyncCHROMIUM(); |
| 182 sharedGL->Flush(); | 188 sharedGL->Flush(); |
| 183 sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData()); | 189 sharedGL->GenSyncTokenCHROMIUM(fenceSync, m_syncToken.GetData()); |
| 184 | 190 |
| 185 sharedGL->BindTexture(GL_TEXTURE_2D, 0); | 191 sharedGL->BindTexture(GL_TEXTURE_2D, 0); |
| 186 // We changed bound textures in this function, so reset the GrContext. | 192 // We changed bound textures in this function, so reset the GrContext. |
| 187 sharedGrContext->resetContext(kTextureBinding_GrGLBackendState); | 193 sharedGrContext->resetContext(kTextureBinding_GrGLBackendState); |
| 188 | 194 |
| 189 m_hasMailbox = true; | 195 m_hasMailbox = true; |
| 190 } | 196 } |
| 191 | 197 |
| 192 void AcceleratedStaticBitmapImage::transfer() { | 198 void AcceleratedStaticBitmapImage::transfer() { |
| 193 checkThread(); | 199 checkThread(); |
| 194 ensureMailbox(); | 200 ensureMailbox(); |
| 195 m_sharedContextId = SharedGpuContext::kNoSharedContext; | 201 m_sharedContextId = SharedGpuContext::kNoSharedContext; |
| 196 // If image thread is set, it means that the image has been consumed on the cu
rrent thread, | 202 // If |m_imageThread| is set, it means that the image has been consumed on the |
| 197 // which may happen when we have chained transfers. When that is the case, we
must not | 203 // current thread, which may happen when we have chained transfers. When that |
| 198 // reset m_imageThread to ensure that releaseImage is called on the right thre
ad. | 204 // is the case, we must not reset |m_imageThread|, so we ensure that |
| 205 // releaseImage() is called on the right thread. |
| 199 if (!m_imageThread) | 206 if (!m_imageThread) |
| 200 m_imageThread = Platform::current()->currentThread(); | 207 m_imageThread = Platform::current()->currentThread(); |
| 201 m_detachThreadAtNextCheck = true; | 208 m_detachThreadAtNextCheck = true; |
| 202 } | 209 } |
| 203 | 210 |
| 204 void AcceleratedStaticBitmapImage::checkThread() { | 211 void AcceleratedStaticBitmapImage::checkThread() { |
| 205 if (m_detachThreadAtNextCheck) { | 212 if (m_detachThreadAtNextCheck) { |
| 206 m_threadChecker.DetachFromThread(); | 213 m_threadChecker.DetachFromThread(); |
| 207 m_detachThreadAtNextCheck = false; | 214 m_detachThreadAtNextCheck = false; |
| 208 } | 215 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 230 m_imageThread->getWebTaskRunner()->postTask( | 237 m_imageThread->getWebTaskRunner()->postTask( |
| 231 BLINK_FROM_HERE, | 238 BLINK_FROM_HERE, |
| 232 crossThreadBind(&releaseImage, passed(std::move(m_image)), | 239 crossThreadBind(&releaseImage, passed(std::move(m_image)), |
| 233 passed(std::move(releaseSyncToken)))); | 240 passed(std::move(releaseSyncToken)))); |
| 234 } | 241 } |
| 235 m_image = nullptr; | 242 m_image = nullptr; |
| 236 m_imageThread = nullptr; | 243 m_imageThread = nullptr; |
| 237 } | 244 } |
| 238 | 245 |
| 239 } // namespace blink | 246 } // namespace blink |
| OLD | NEW |