| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| 11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
| 12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
| 13 * | 13 * |
| 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "platform/graphics/Canvas2DLayerBridge.h" | 26 #include "platform/graphics/Canvas2DLayerBridge.h" |
| 27 | 27 |
| 28 #include "base/memory/ptr_util.h" |
| 29 #include "cc/resources/single_release_callback.h" |
| 30 #include "cc/resources/texture_mailbox.h" |
| 28 #include "gpu/command_buffer/client/gles2_interface.h" | 31 #include "gpu/command_buffer/client/gles2_interface.h" |
| 29 #include "platform/Histogram.h" | 32 #include "platform/Histogram.h" |
| 30 #include "platform/RuntimeEnabledFeatures.h" | 33 #include "platform/RuntimeEnabledFeatures.h" |
| 31 #include "platform/TraceEvent.h" | 34 #include "platform/TraceEvent.h" |
| 32 #include "platform/graphics/CanvasMetrics.h" | 35 #include "platform/graphics/CanvasMetrics.h" |
| 33 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" | 36 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" |
| 34 #include "platform/graphics/GraphicsLayer.h" | 37 #include "platform/graphics/GraphicsLayer.h" |
| 35 #include "platform/graphics/ImageBuffer.h" | 38 #include "platform/graphics/ImageBuffer.h" |
| 36 #include "platform/graphics/gpu/SharedContextRateLimiter.h" | 39 #include "platform/graphics/gpu/SharedContextRateLimiter.h" |
| 37 #include "public/platform/Platform.h" | 40 #include "public/platform/Platform.h" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 // a 'PreferAcceleration' operation. | 190 // a 'PreferAcceleration' operation. |
| 188 return shouldAccelerate(PreferAcceleration); | 191 return shouldAccelerate(PreferAcceleration); |
| 189 } | 192 } |
| 190 | 193 |
| 191 GLenum Canvas2DLayerBridge::getGLFilter() | 194 GLenum Canvas2DLayerBridge::getGLFilter() |
| 192 { | 195 { |
| 193 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; | 196 return m_filterQuality == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; |
| 194 } | 197 } |
| 195 | 198 |
| 196 #if USE_IOSURFACE_FOR_2D_CANVAS | 199 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 197 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage(SkImage* image, WebEx
ternalTextureMailbox* outMailbox) | 200 bool Canvas2DLayerBridge::prepareIOSurfaceMailboxFromImage(SkImage* image, cc::T
extureMailbox* outMailbox) |
| 198 { | 201 { |
| 199 // Need to flush skia's internal queue because texture is about to be access
ed directly | 202 // Need to flush skia's internal queue because texture is about to be access
ed directly |
| 200 GrContext* grContext = m_contextProvider->grContext(); | 203 GrContext* grContext = m_contextProvider->grContext(); |
| 201 grContext->flush(); | 204 grContext->flush(); |
| 202 | 205 |
| 203 ImageInfo imageInfo = createIOSurfaceBackedTexture(); | 206 ImageInfo imageInfo = createIOSurfaceBackedTexture(); |
| 204 if (imageInfo.empty()) | 207 if (imageInfo.empty()) |
| 205 return false; | 208 return false; |
| 206 | 209 |
| 207 gpu::gles2::GLES2Interface* gl = contextGL(); | 210 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 208 if (!gl) | 211 if (!gl) |
| 209 return false; | 212 return false; |
| 210 | 213 |
| 211 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu
reHandle(true))->fID; | 214 GLuint imageTexture = skia::GrBackendObjectToGrGLTextureInfo(image->getTextu
reHandle(true))->fID; |
| 212 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0,
m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 215 gl->CopySubTextureCHROMIUM(imageTexture, imageInfo.m_textureId, 0, 0, 0, 0,
m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); |
| 213 | 216 |
| 214 MailboxInfo& info = m_mailboxes.first(); | 217 MailboxInfo& info = m_mailboxes.first(); |
| 215 info.m_mailbox.textureTarget = GC3D_TEXTURE_RECTANGLE_ARB; | 218 uint32_t textureTarget = GC3D_TEXTURE_RECTANGLE_ARB; |
| 216 gl->GenMailboxCHROMIUM(info.m_mailbox.name); | 219 gpu::Mailbox mailbox; |
| 217 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, info.m_mailbox.textu
reTarget, info.m_mailbox.name); | 220 gl->GenMailboxCHROMIUM(mailbox.name); |
| 218 info.m_mailbox.allowOverlay = true; | 221 gl->ProduceTextureDirectCHROMIUM(imageInfo.m_textureId, textureTarget, mailb
ox.name); |
| 219 | 222 |
| 220 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 223 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| 221 gl->Flush(); | 224 gl->Flush(); |
| 222 gl->GenSyncTokenCHROMIUM(fenceSync, info.m_mailbox.syncToken); | 225 gpu::SyncToken syncToken; |
| 223 info.m_mailbox.validSyncToken = true; | 226 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); |
| 224 | 227 |
| 225 info.m_imageInfo = imageInfo; | 228 info.m_imageInfo = imageInfo; |
| 226 *outMailbox = info.m_mailbox; | 229 bool isOverlayCandidate = true; |
| 230 bool secureOutputOnly = false; |
| 231 info.m_mailbox = mailbox; |
| 232 *outMailbox = cc::TextureMailbox(mailbox, syncToken, textureTarget, gfx::Siz
e(m_size.width(), m_size.height()), isOverlayCandidate, secureOutputOnly); |
| 227 | 233 |
| 228 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); | 234 gl->BindTexture(GC3D_TEXTURE_RECTANGLE_ARB, 0); |
| 229 | 235 |
| 230 // Because we are changing the texture binding without going through skia, | 236 // Because we are changing the texture binding without going through skia, |
| 231 // we must dirty the context. | 237 // we must dirty the context. |
| 232 grContext->resetContext(kTextureBinding_GrGLBackendState); | 238 grContext->resetContext(kTextureBinding_GrGLBackendState); |
| 233 | 239 |
| 234 return true; | 240 return true; |
| 235 } | 241 } |
| 236 | 242 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 294 } |
| 289 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 295 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 290 | 296 |
| 291 void Canvas2DLayerBridge::createMailboxInfo() | 297 void Canvas2DLayerBridge::createMailboxInfo() |
| 292 { | 298 { |
| 293 MailboxInfo tmp; | 299 MailboxInfo tmp; |
| 294 tmp.m_parentLayerBridge = this; | 300 tmp.m_parentLayerBridge = this; |
| 295 m_mailboxes.prepend(tmp); | 301 m_mailboxes.prepend(tmp); |
| 296 } | 302 } |
| 297 | 303 |
| 298 bool Canvas2DLayerBridge::prepareMailboxFromImage(PassRefPtr<SkImage> image, Web
ExternalTextureMailbox* outMailbox) | 304 bool Canvas2DLayerBridge::prepareMailboxFromImage(PassRefPtr<SkImage> image, |
| 305 cc::TextureMailbox* outMailbox) |
| 299 { | 306 { |
| 300 createMailboxInfo(); | 307 createMailboxInfo(); |
| 301 MailboxInfo& mailboxInfo = m_mailboxes.first(); | 308 MailboxInfo& mailboxInfo = m_mailboxes.first(); |
| 302 mailboxInfo.m_mailbox.nearestNeighbor = getGLFilter() == GL_NEAREST; | |
| 303 mailboxInfo.m_mailbox.textureSize = WebSize(m_size.width(), m_size.height())
; | |
| 304 | 309 |
| 305 GrContext* grContext = m_contextProvider->grContext(); | 310 GrContext* grContext = m_contextProvider->grContext(); |
| 306 if (!grContext) { | 311 if (!grContext) { |
| 307 mailboxInfo.m_image = image; | 312 mailboxInfo.m_image = image; |
| 308 return true; // for testing: skip gl stuff when using a mock graphics co
ntext. | 313 return true; // for testing: skip gl stuff when using a mock graphics co
ntext. |
| 309 } | 314 } |
| 310 | 315 |
| 311 #if USE_IOSURFACE_FOR_2D_CANVAS | 316 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 312 if (RuntimeEnabledFeatures::canvas2dImageChromiumEnabled()) { | 317 if (RuntimeEnabledFeatures::canvas2dImageChromiumEnabled()) { |
| 313 if (prepareIOSurfaceMailboxFromImage(image.get(), outMailbox)) | 318 if (prepareIOSurfaceMailboxFromImage(image.get(), outMailbox)) |
| 314 return true; | 319 return true; |
| 315 // Note: if IOSurface backed texture creation failed we fall back to the | 320 // Note: if IOSurface backed texture creation failed we fall back to the |
| 316 // non-IOSurface path. | 321 // non-IOSurface path. |
| 317 } | 322 } |
| 318 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 323 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 319 | 324 |
| 320 mailboxInfo.m_image = image; | 325 mailboxInfo.m_image = image; |
| 321 | 326 |
| 322 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled()) | 327 if (RuntimeEnabledFeatures::forceDisable2dCanvasCopyOnWriteEnabled()) |
| 323 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode)
; | 328 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode)
; |
| 324 | 329 |
| 325 // Need to flush skia's internal queue because texture is about to be access
ed directly | 330 // Need to flush skia's internal queue because texture is about to be access
ed directly |
| 326 grContext->flush(); | 331 grContext->flush(); |
| 327 | 332 |
| 328 // Because of texture sharing with the compositor, we must invalidate | 333 // Because of texture sharing with the compositor, we must invalidate |
| 329 // the state cached in skia so that the deferred copy on write | 334 // the state cached in skia so that the deferred copy on write |
| 330 // in SkSurface_Gpu does not make any false assumptions. | 335 // in SkSurface_Gpu does not make any false assumptions. |
| 331 mailboxInfo.m_image->getTexture()->textureParamsModified(); | 336 mailboxInfo.m_image->getTexture()->textureParamsModified(); |
| 332 mailboxInfo.m_mailbox.textureTarget = GL_TEXTURE_2D; | |
| 333 | 337 |
| 334 gpu::gles2::GLES2Interface* gl = contextGL(); | 338 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 335 if (!gl) | 339 if (!gl) |
| 336 return false; | 340 return false; |
| 337 | 341 |
| 338 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag
e->getTextureHandle(true))->fID; | 342 GLuint textureID = skia::GrBackendObjectToGrGLTextureInfo(mailboxInfo.m_imag
e->getTextureHandle(true))->fID; |
| 339 gl->BindTexture(GL_TEXTURE_2D, textureID); | 343 gl->BindTexture(GL_TEXTURE_2D, textureID); |
| 340 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter()); | 344 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter()); |
| 341 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter()); | 345 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter()); |
| 342 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 346 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 343 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 347 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 344 | 348 |
| 345 gl->GenMailboxCHROMIUM(mailboxInfo.m_mailbox.name); | 349 gpu::Mailbox mailbox; |
| 346 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo.m_mailbox.name); | 350 gl->GenMailboxCHROMIUM(mailbox.name); |
| 351 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
| 347 | 352 |
| 353 gpu::SyncToken syncToken; |
| 348 if (isHidden()) { | 354 if (isHidden()) { |
| 349 // With hidden canvases, we release the SkImage immediately because | 355 // With hidden canvases, we release the SkImage immediately because |
| 350 // there is no need for animations to be double buffered. | 356 // there is no need for animations to be double buffered. |
| 351 mailboxInfo.m_image.clear(); | 357 mailboxInfo.m_image.clear(); |
| 352 } else { | 358 } else { |
| 353 // FIXME: We'd rather insert a syncpoint than perform a flush here, | 359 // FIXME: We'd rather insert a syncpoint than perform a flush here, |
| 354 // but currently the canvas will flicker if we don't flush here. | 360 // but currently the canvas will flicker if we don't flush here. |
| 355 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 361 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| 356 gl->Flush(); | 362 gl->Flush(); |
| 357 gl->GenSyncTokenCHROMIUM(fenceSync, mailboxInfo.m_mailbox.syncToken); | 363 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); |
| 358 mailboxInfo.m_mailbox.validSyncToken = true; | |
| 359 } | 364 } |
| 365 mailboxInfo.m_mailbox = mailbox; |
| 366 *outMailbox = cc::TextureMailbox(mailbox, syncToken, GL_TEXTURE_2D); |
| 367 |
| 360 gl->BindTexture(GL_TEXTURE_2D, 0); | 368 gl->BindTexture(GL_TEXTURE_2D, 0); |
| 361 // Because we are changing the texture binding without going through skia, | 369 // Because we are changing the texture binding without going through skia, |
| 362 // we must dirty the context. | 370 // we must dirty the context. |
| 363 grContext->resetContext(kTextureBinding_GrGLBackendState); | 371 grContext->resetContext(kTextureBinding_GrGLBackendState); |
| 364 | |
| 365 *outMailbox = mailboxInfo.m_mailbox; | |
| 366 return true; | 372 return true; |
| 367 } | 373 } |
| 368 | 374 |
| 369 void Canvas2DLayerBridge::resetSkiaTextureBinding() | 375 void Canvas2DLayerBridge::resetSkiaTextureBinding() |
| 370 { | 376 { |
| 371 GrContext* grContext = m_contextProvider->grContext(); | 377 GrContext* grContext = m_contextProvider->grContext(); |
| 372 if (grContext) | 378 if (grContext) |
| 373 grContext->resetContext(kTextureBinding_GrGLBackendState); | 379 grContext->resetContext(kTextureBinding_GrGLBackendState); |
| 374 } | 380 } |
| 375 | 381 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 m_surface = surface.release(); | 764 m_surface = surface.release(); |
| 759 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 | 765 // FIXME: draw sad canvas picture into new buffer crbug.com/243842 |
| 760 } | 766 } |
| 761 } | 767 } |
| 762 if (m_imageBuffer) | 768 if (m_imageBuffer) |
| 763 m_imageBuffer->updateGPUMemoryUsage(); | 769 m_imageBuffer->updateGPUMemoryUsage(); |
| 764 | 770 |
| 765 return m_surface.get(); | 771 return m_surface.get(); |
| 766 } | 772 } |
| 767 | 773 |
| 768 bool Canvas2DLayerBridge::prepareMailbox(WebExternalTextureMailbox* outMailbox,
WebExternalBitmap* bitmap) | 774 bool Canvas2DLayerBridge::PrepareTextureMailbox( |
| 775 cc::TextureMailbox* outMailbox, |
| 776 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, |
| 777 bool useSharedMemory) |
| 769 { | 778 { |
| 770 if (m_destructionInProgress) { | 779 if (m_destructionInProgress) { |
| 771 // It can be hit in the following sequence. | 780 // It can be hit in the following sequence. |
| 772 // 1. Canvas draws something. | 781 // 1. Canvas draws something. |
| 773 // 2. The compositor begins the frame. | 782 // 2. The compositor begins the frame. |
| 774 // 3. Javascript makes a context be lost. | 783 // 3. Javascript makes a context be lost. |
| 775 // 4. Here. | 784 // 4. Here. |
| 776 return false; | 785 return false; |
| 777 } | 786 } |
| 778 DCHECK(isAccelerated() || isHibernating() || m_softwareRenderingWhileHidden)
; | 787 DCHECK(isAccelerated() || isHibernating() || m_softwareRenderingWhileHidden)
; |
| 779 | 788 |
| 780 // if hibernating but not hidden, we want to wake up from | 789 // if hibernating but not hidden, we want to wake up from |
| 781 // hibernation | 790 // hibernation |
| 782 if ((isHibernating() || m_softwareRenderingWhileHidden) && isHidden()) | 791 if ((isHibernating() || m_softwareRenderingWhileHidden) && isHidden()) |
| 783 return false; | 792 return false; |
| 784 | 793 |
| 785 if (bitmap) { | 794 // TODO(danakj): This means the compositor has dropped to software |
| 786 // Using accelerated 2d canvas with software renderer, which | 795 // compositing. Our context should already be lost if cc can't make a |
| 787 // should only happen in tests that use fake graphics contexts | 796 // context that it can use (each time it tries it loses our context). |
| 788 // or in Android WebView in software mode. In this case, we do | 797 // But checkSurfaceValid() returns true even tho there is a GL error |
| 789 // not care about producing any results for this canvas. | 798 // sometimes.. so not sure if just checking for a GL error is right here |
| 790 skipQueuedDrawCommands(); | 799 // or what. |
| 791 m_lastImageId = 0; | 800 if (useSharedMemory) { |
| 801 // Since we're going to software compositing, this class will soon be |
| 802 // destroyed for software mode canvas. |
| 792 return false; | 803 return false; |
| 793 } | 804 } |
| 794 | 805 |
| 795 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration, SnapshotReasonU
nknown); | 806 RefPtr<SkImage> image = newImageSnapshot(PreferAcceleration, SnapshotReasonU
nknown); |
| 796 if (!image || !image->getTexture()) | 807 if (!image || !image->getTexture()) |
| 797 return false; | 808 return false; |
| 798 | 809 |
| 799 // Early exit if canvas was not drawn to since last prepareMailbox. | 810 // Early exit if canvas was not drawn to since last prepareMailbox. |
| 800 GLenum filter = getGLFilter(); | 811 GLenum filter = getGLFilter(); |
| 801 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) | 812 if (image->uniqueID() == m_lastImageId && filter == m_lastFilter) |
| 802 return false; | 813 return false; |
| 803 m_lastImageId = image->uniqueID(); | 814 m_lastImageId = image->uniqueID(); |
| 804 m_lastFilter = filter; | 815 m_lastFilter = filter; |
| 805 | 816 |
| 806 return prepareMailboxFromImage(image.release(), outMailbox); | 817 if (!prepareMailboxFromImage(image.release(), outMailbox)) |
| 818 return false; |
| 819 outMailbox->set_nearest_neighbor(getGLFilter() == GL_NEAREST); |
| 820 |
| 821 auto func = WTF::bind(&Canvas2DLayerBridge::mailboxReleased, |
| 822 m_weakPtrFactory.createWeakPtr(), |
| 823 outMailbox->mailbox()); |
| 824 *outReleaseCallback = cc::SingleReleaseCallback::Create( |
| 825 convertToBaseCallback(std::move(func))); |
| 826 return true; |
| 807 } | 827 } |
| 808 | 828 |
| 809 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailb
ox, bool lostResource) | 829 void Canvas2DLayerBridge::mailboxReleased(const gpu::Mailbox& mailbox, |
| 830 const gpu::SyncToken& syncToken, |
| 831 bool lostResource) |
| 810 { | 832 { |
| 811 DCHECK(isAccelerated() || isHibernating()); | 833 DCHECK(isAccelerated() || isHibernating()); |
| 812 bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->con
textGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR); | 834 bool contextLost = !isHibernating() && (!m_surface || m_contextProvider->con
textGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR); |
| 813 DCHECK(m_mailboxes.last().m_parentLayerBridge.get() == this); | 835 DCHECK(m_mailboxes.last().m_parentLayerBridge.get() == this); |
| 814 | 836 |
| 815 // Mailboxes are typically released in FIFO order, so we iterate | 837 // Mailboxes are typically released in FIFO order, so we iterate |
| 816 // from the end of m_mailboxes. | 838 // from the end of m_mailboxes. |
| 817 auto releasedMailboxInfo = m_mailboxes.end(); | 839 auto releasedMailboxInfo = m_mailboxes.end(); |
| 818 auto firstMailbox = m_mailboxes.begin(); | 840 auto firstMailbox = m_mailboxes.begin(); |
| 819 | 841 |
| 820 while (true) { | 842 while (true) { |
| 821 --releasedMailboxInfo; | 843 --releasedMailboxInfo; |
| 822 if (nameEquals(releasedMailboxInfo->m_mailbox, mailbox)) { | 844 if (releasedMailboxInfo->m_mailbox == mailbox) |
| 823 break; | 845 break; |
| 824 } | |
| 825 DCHECK(releasedMailboxInfo != firstMailbox); | 846 DCHECK(releasedMailboxInfo != firstMailbox); |
| 826 } | 847 } |
| 827 | 848 |
| 828 if (!contextLost) { | 849 if (!contextLost) { |
| 829 // Invalidate texture state in case the compositor altered it since the
copy-on-write. | 850 // Invalidate texture state in case the compositor altered it since the
copy-on-write. |
| 830 if (releasedMailboxInfo->m_image) { | 851 if (releasedMailboxInfo->m_image) { |
| 831 #if USE_IOSURFACE_FOR_2D_CANVAS | 852 #if USE_IOSURFACE_FOR_2D_CANVAS |
| 832 DCHECK(releasedMailboxInfo->m_imageInfo.empty()); | 853 DCHECK(releasedMailboxInfo->m_imageInfo.empty()); |
| 833 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 854 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 834 if (mailbox.validSyncToken) { | 855 if (syncToken.HasData()) { |
| 835 contextGL()->WaitSyncTokenCHROMIUM(mailbox.syncToken); | 856 contextGL()->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); |
| 836 } | 857 } |
| 837 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); | 858 GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); |
| 838 if (texture) { | 859 if (texture) { |
| 839 if (lostResource) { | 860 if (lostResource) { |
| 840 texture->abandon(); | 861 texture->abandon(); |
| 841 } else { | 862 } else { |
| 842 texture->textureParamsModified(); | 863 texture->textureParamsModified(); |
| 843 // Break the mailbox association to avoid leaking mailboxes
every time skia recycles a texture. | 864 // Break the mailbox association to avoid leaking mailboxes
every time skia recycles a texture. |
| 844 gpu::gles2::GLES2Interface* gl = contextGL(); | 865 gpu::gles2::GLES2Interface* gl = contextGL(); |
| 845 if (gl) | 866 if (gl) |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 DCHECK(imageId); | 992 DCHECK(imageId); |
| 972 DCHECK(textureId); | 993 DCHECK(textureId); |
| 973 } | 994 } |
| 974 | 995 |
| 975 bool Canvas2DLayerBridge::ImageInfo::empty() | 996 bool Canvas2DLayerBridge::ImageInfo::empty() |
| 976 { | 997 { |
| 977 return m_imageId == 0; | 998 return m_imageId == 0; |
| 978 } | 999 } |
| 979 #endif // USE_IOSURFACE_FOR_2D_CANVAS | 1000 #endif // USE_IOSURFACE_FOR_2D_CANVAS |
| 980 | 1001 |
| 981 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) | 1002 Canvas2DLayerBridge::MailboxInfo::MailboxInfo() = default; |
| 982 { | 1003 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) = defaul
t; |
| 983 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); | |
| 984 m_image = other.m_image; | |
| 985 m_parentLayerBridge = other.m_parentLayerBridge; | |
| 986 #if USE_IOSURFACE_FOR_2D_CANVAS | |
| 987 m_imageInfo = other.m_imageInfo; | |
| 988 #endif // USE_IOSURFACE_FOR_2D_CANVAS | |
| 989 } | |
| 990 | 1004 |
| 991 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) | 1005 void Canvas2DLayerBridge::Logger::reportHibernationEvent(HibernationEvent event) |
| 992 { | 1006 { |
| 993 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib
ernationEvents", HibernationEventCount)); | 1007 DEFINE_STATIC_LOCAL(EnumerationHistogram, hibernationHistogram, ("Canvas.Hib
ernationEvents", HibernationEventCount)); |
| 994 hibernationHistogram.count(event); | 1008 hibernationHistogram.count(event); |
| 995 } | 1009 } |
| 996 | 1010 |
| 997 } // namespace blink | 1011 } // namespace blink |
| OLD | NEW |