| 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 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 #include "platform/graphics/gpu/SharedGraphicsContext3D.h" | 36 #include "platform/graphics/gpu/SharedGraphicsContext3D.h" |
| 37 #include "public/platform/Platform.h" | 37 #include "public/platform/Platform.h" |
| 38 #include "public/platform/WebCompositorSupport.h" | 38 #include "public/platform/WebCompositorSupport.h" |
| 39 #include "public/platform/WebGraphicsContext3D.h" | 39 #include "public/platform/WebGraphicsContext3D.h" |
| 40 | 40 |
| 41 using blink::WebExternalTextureLayer; | 41 using blink::WebExternalTextureLayer; |
| 42 using blink::WebGraphicsContext3D; | 42 using blink::WebGraphicsContext3D; |
| 43 | 43 |
| 44 namespace WebCore { | 44 namespace WebCore { |
| 45 | 45 |
| 46 void Canvas2DLayerBridgePtr::clear() | 46 static PassRefPtr<SkSurface> createSkSurface(GraphicsContext3D* context3D, const
IntSize& size, int msaaSampleCount) |
| 47 { | |
| 48 if (m_ptr) { | |
| 49 m_ptr->destroy(); | |
| 50 m_ptr.clear(); | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 Canvas2DLayerBridgePtr& Canvas2DLayerBridgePtr::operator=(const PassRefPtr<Canva
s2DLayerBridge>& other) | |
| 55 { | |
| 56 clear(); | |
| 57 m_ptr = other; | |
| 58 return *this; | |
| 59 } | |
| 60 | |
| 61 static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& siz
e, int msaaSampleCount) | |
| 62 { | 47 { |
| 63 ASSERT(!context3D->webContext()->isContextLost()); | 48 ASSERT(!context3D->webContext()->isContextLost()); |
| 64 GrContext* gr = context3D->grContext(); | 49 GrContext* gr = context3D->grContext(); |
| 65 if (!gr) | 50 if (!gr) |
| 66 return 0; | 51 return 0; |
| 67 gr->resetContext(); | 52 gr->resetContext(); |
| 68 SkImageInfo info; | 53 SkImageInfo info; |
| 69 info.fWidth = size.width(); | 54 info.fWidth = size.width(); |
| 70 info.fHeight = size.height(); | 55 info.fHeight = size.height(); |
| 71 info.fColorType = kPMColor_SkColorType; | 56 info.fColorType = kPMColor_SkColorType; |
| 72 info.fAlphaType = kPremul_SkAlphaType; | 57 info.fAlphaType = kPremul_SkAlphaType; |
| 73 return SkSurface::NewRenderTarget(gr, info, msaaSampleCount); | 58 return adoptRef(SkSurface::NewRenderTarget(gr, info, msaaSampleCount)); |
| 74 } | 59 } |
| 75 | 60 |
| 76 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassRefPtr<GraphicsC
ontext3D> context, const IntSize& size, OpacityMode opacityMode, int msaaSampleC
ount) | 61 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size,
OpacityMode opacityMode, int msaaSampleCount) |
| 77 { | 62 { |
| 78 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 63 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| 79 SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size, msaaSampl
eCount)); | 64 RefPtr<GraphicsContext3D> context = SharedGraphicsContext3D::get(); |
| 80 if (!surface.get()) { | 65 RefPtr<SkSurface> surface(createSkSurface(context.get(), size, msaaSampleCou
nt)); |
| 81 return PassRefPtr<Canvas2DLayerBridge>(); | 66 if (!surface) |
| 82 } | 67 return 0; |
| 83 RefPtr<SkDeferredCanvas> canvas = adoptRef(SkDeferredCanvas::Create(surface.
get())); | 68 RefPtr<Canvas2DLayerBridge> layerBridge; |
| 84 RefPtr<Canvas2DLayerBridge> layerBridge = adoptRef(new Canvas2DLayerBridge(c
ontext, canvas.release(), msaaSampleCount, opacityMode)); | 69 OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface.
get())); |
| 70 layerBridge = adoptRef(new Canvas2DLayerBridge(context, canvas.release(), ms
aaSampleCount, opacityMode)); |
| 85 return layerBridge.release(); | 71 return layerBridge.release(); |
| 86 } | 72 } |
| 87 | 73 |
| 88 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context,
PassRefPtr<SkDeferredCanvas> canvas, int msaaSampleCount, OpacityMode opacityMod
e) | 74 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context,
PassOwnPtr<SkDeferredCanvas> canvas, int msaaSampleCount, OpacityMode opacityMod
e) |
| 89 : m_canvas(canvas) | 75 : m_canvas(canvas) |
| 90 , m_context(context) | 76 , m_context(context) |
| 91 , m_msaaSampleCount(msaaSampleCount) | 77 , m_msaaSampleCount(msaaSampleCount) |
| 92 , m_bytesAllocated(0) | 78 , m_bytesAllocated(0) |
| 93 , m_didRecordDrawCommand(false) | 79 , m_didRecordDrawCommand(false) |
| 94 , m_surfaceIsValid(true) | 80 , m_surfaceIsValid(true) |
| 95 , m_framesPending(0) | 81 , m_framesPending(0) |
| 96 , m_destructionInProgress(false) | 82 , m_destructionInProgress(false) |
| 97 , m_rateLimitingEnabled(false) | 83 , m_rateLimitingEnabled(false) |
| 98 , m_next(0) | 84 , m_next(0) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 122 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); | 108 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); |
| 123 mailboxInfo->m_mailbox.syncPoint = 0; | 109 mailboxInfo->m_mailbox.syncPoint = 0; |
| 124 } | 110 } |
| 125 // Invalidate texture state in case the compositor altered it since
the copy-on-write. | 111 // Invalidate texture state in case the compositor altered it since
the copy-on-write. |
| 126 mailboxInfo->m_image->getTexture()->invalidateCachedState(); | 112 mailboxInfo->m_image->getTexture()->invalidateCachedState(); |
| 127 } | 113 } |
| 128 } | 114 } |
| 129 m_mailboxes.clear(); | 115 m_mailboxes.clear(); |
| 130 } | 116 } |
| 131 | 117 |
| 132 void Canvas2DLayerBridge::destroy() | 118 void Canvas2DLayerBridge::beginDestruction() |
| 133 { | 119 { |
| 134 ASSERT(!m_destructionInProgress); | 120 ASSERT(!m_destructionInProgress); |
| 135 m_destructionInProgress = true; | 121 m_destructionInProgress = true; |
| 136 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 122 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 137 m_canvas->setNotificationClient(0); | 123 m_canvas->setNotificationClient(0); |
| 138 m_layer->clearTexture(); | 124 m_layer->clearTexture(); |
| 139 Canvas2DLayerManager::get().layerToBeDestroyed(this); | 125 Canvas2DLayerManager::get().layerToBeDestroyed(this); |
| 140 // Orphaning the layer is required to trigger the recration of a new layer | 126 // Orphaning the layer is required to trigger the recration of a new layer |
| 141 // in the case where destruction is caused by a canvas resize. Test: | 127 // in the case where destruction is caused by a canvas resize. Test: |
| 142 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html | 128 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 | 211 |
| 226 void Canvas2DLayerBridge::flush() | 212 void Canvas2DLayerBridge::flush() |
| 227 { | 213 { |
| 228 ASSERT(!m_destructionInProgress); | 214 ASSERT(!m_destructionInProgress); |
| 229 if (m_canvas->hasPendingCommands()) { | 215 if (m_canvas->hasPendingCommands()) { |
| 230 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); | 216 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); |
| 231 m_canvas->flush(); | 217 m_canvas->flush(); |
| 232 } | 218 } |
| 233 } | 219 } |
| 234 | 220 |
| 235 WebGraphicsContext3D* Canvas2DLayerBridge::context() | 221 blink::WebGraphicsContext3D* Canvas2DLayerBridge::context() |
| 236 { | 222 { |
| 237 // Check on m_layer is necessary because context() may be called during | 223 // Check on m_layer is necessary because context() may be called during |
| 238 // the destruction of m_layer | 224 // the destruction of m_layer |
| 239 if (m_layer) { | 225 if (m_layer) { |
| 240 isValid(); // To ensure rate limiter is disabled if context is lost. | 226 isValid(); // To ensure rate limiter is disabled if context is lost. |
| 241 } | 227 } |
| 242 return m_context->webContext(); | 228 return m_context->webContext(); |
| 243 } | 229 } |
| 244 | 230 |
| 245 bool Canvas2DLayerBridge::isValid() | 231 bool Canvas2DLayerBridge::isValid() |
| 246 { | 232 { |
| 247 ASSERT(m_layer); | 233 ASSERT(m_layer); |
| 248 if (m_destructionInProgress) | 234 if (m_destructionInProgress) |
| 249 return false; | 235 return false; |
| 250 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { | 236 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { |
| 251 // Attempt to recover. | 237 // Attempt to recover. |
| 252 m_layer->clearTexture(); | 238 m_layer->clearTexture(); |
| 253 m_mailboxes.clear(); | 239 m_mailboxes.clear(); |
| 254 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get()
; | 240 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get()
; |
| 255 if (!sharedContext || sharedContext->webContext()->isContextLost()) { | 241 if (!sharedContext || sharedContext->webContext()->isContextLost()) { |
| 256 m_surfaceIsValid = false; | 242 m_surfaceIsValid = false; |
| 257 } else { | 243 } else { |
| 258 m_context = sharedContext; | 244 m_context = sharedContext; |
| 259 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi
ce()->height()); | 245 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi
ce()->height()); |
| 260 SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size,
m_msaaSampleCount)); | 246 RefPtr<SkSurface> surface(createSkSurface(m_context.get(), size, m_m
saaSampleCount)); |
| 261 if (surface.get()) { | 247 if (surface.get()) { |
| 262 m_canvas->setSurface(surface.get()); | 248 m_canvas->setSurface(surface.get()); |
| 263 m_surfaceIsValid = true; | 249 m_surfaceIsValid = true; |
| 264 // FIXME: draw sad canvas picture into new buffer crbug.com/2438
42 | 250 // FIXME: draw sad canvas picture into new buffer crbug.com/2438
42 |
| 265 } else { | 251 } else { |
| 266 // Surface allocation failed. Set m_surfaceIsValid to false to | 252 // Surface allocation failed. Set m_surfaceIsValid to false to |
| 267 // trigger subsequent retry. | 253 // trigger subsequent retry. |
| 268 m_surfaceIsValid = false; | 254 m_surfaceIsValid = false; |
| 269 } | 255 } |
| 270 } | 256 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 // Trigger Canvas2DLayerBridge self-destruction if this is the | 364 // Trigger Canvas2DLayerBridge self-destruction if this is the |
| 379 // last live mailbox and the layer bridge is not externally | 365 // last live mailbox and the layer bridge is not externally |
| 380 // referenced. | 366 // referenced. |
| 381 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this); | 367 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this); |
| 382 mailboxInfo->m_parentLayerBridge.clear(); | 368 mailboxInfo->m_parentLayerBridge.clear(); |
| 383 return; | 369 return; |
| 384 } | 370 } |
| 385 } | 371 } |
| 386 } | 372 } |
| 387 | 373 |
| 388 blink::WebLayer* Canvas2DLayerBridge::layer() | 374 blink::WebLayer* Canvas2DLayerBridge::layer() const |
| 389 { | 375 { |
| 390 ASSERT(m_layer); | 376 ASSERT(m_layer); |
| 391 return m_layer->layer(); | 377 return m_layer->layer(); |
| 392 } | 378 } |
| 393 | 379 |
| 394 void Canvas2DLayerBridge::contextAcquired() | 380 void Canvas2DLayerBridge::willUse() |
| 395 { | 381 { |
| 396 ASSERT(!m_destructionInProgress); | 382 ASSERT(!m_destructionInProgress); |
| 397 Canvas2DLayerManager::get().layerDidDraw(this); | 383 Canvas2DLayerManager::get().layerDidDraw(this); |
| 398 m_didRecordDrawCommand = true; | 384 m_didRecordDrawCommand = true; |
| 399 } | 385 } |
| 400 | 386 |
| 401 unsigned Canvas2DLayerBridge::backBufferTexture() | 387 Platform3DObject Canvas2DLayerBridge::getBackingTexture() |
| 402 { | 388 { |
| 403 ASSERT(!m_destructionInProgress); | 389 ASSERT(!m_destructionInProgress); |
| 404 if (!isValid()) | 390 if (!isValid()) |
| 405 return 0; | 391 return 0; |
| 406 contextAcquired(); | 392 willUse(); |
| 407 m_canvas->flush(); | 393 m_canvas->flush(); |
| 408 m_context->flush(); | 394 m_context->flush(); |
| 409 GrRenderTarget* renderTarget = reinterpret_cast<GrRenderTarget*>(m_canvas->g
etDevice()->accessRenderTarget()); | 395 GrRenderTarget* renderTarget = m_canvas->getTopDevice()->accessRenderTarget(
); |
| 410 if (renderTarget) { | 396 if (renderTarget) { |
| 411 return renderTarget->asTexture()->getTextureHandle(); | 397 return renderTarget->asTexture()->getTextureHandle(); |
| 412 } | 398 } |
| 413 return 0; | 399 return 0; |
| 414 } | 400 } |
| 415 | 401 |
| 416 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { | 402 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { |
| 417 // This copy constructor should only be used for Vector reallocation | 403 // This copy constructor should only be used for Vector reallocation |
| 418 // Assuming 'other' is to be destroyed, we swap m_image ownership | 404 // Assuming 'other' is to be destroyed, we swap m_image ownership |
| 419 // rather than do a refcount dance. | 405 // rather than do a refcount dance. |
| 420 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); | 406 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); |
| 421 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); | 407 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); |
| 422 m_status = other.m_status; | 408 m_status = other.m_status; |
| 423 } | 409 } |
| 424 | 410 |
| 425 } | 411 } |
| OLD | NEW |