Chromium Code Reviews| Index: Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| diff --git a/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp b/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| index 3e9a705859bed05d9177823dc8e2cc40cb2aba9d..ca0887e02f0870dfc9d96be94da03b6157d4f91b 100644 |
| --- a/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| +++ b/Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp |
| @@ -44,35 +44,18 @@ using WebKit::WebGraphicsContext3D; |
| namespace WebCore { |
| -static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& size) |
| -{ |
| - ASSERT(!context3D->webContext()->isContextLost()); |
| - GrContext* gr = context3D->grContext(); |
| - if (!gr) |
| - return 0; |
| - gr->resetContext(); |
| - SkImage::Info info; |
| - info.fWidth = size.width(); |
| - info.fHeight = size.height(); |
| - info.fColorType = SkImage::kPMColor_ColorType; |
| - info.fAlphaType = SkImage::kPremul_AlphaType; |
| - return SkSurface::NewRenderTarget(gr, info); |
| -} |
| - |
| -PassOwnPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassRefPtr<GraphicsContext3D> context, const IntSize& size, OpacityMode opacityMode) |
| +PassOwnPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassOwnPtr<Helper> helper, const IntSize& size, OpacityMode opacityMode) |
| { |
| TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| - SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size)); |
| - if (!surface.get()) |
| - return PassOwnPtr<Canvas2DLayerBridge>(); |
| - SkDeferredCanvas* canvas = new SkDeferredCanvas(surface); |
| - OwnPtr<Canvas2DLayerBridge> layerBridge = adoptPtr(new Canvas2DLayerBridge(context, canvas, opacityMode)); |
| + bool success; |
| + OwnPtr<Canvas2DLayerBridge> layerBridge = adoptPtr(new Canvas2DLayerBridge(helper, size, opacityMode, &success)); |
| + if (!success) |
| + layerBridge.clear(); |
| return layerBridge.release(); |
| } |
| -Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, SkDeferredCanvas* canvas, OpacityMode opacityMode) |
| - : m_canvas(canvas) |
| - , m_context(context) |
| +Canvas2DLayerBridge::Canvas2DLayerBridge(PassOwnPtr<Helper> helper, const IntSize& size, OpacityMode opacityMode, bool* success) |
| + : m_helper(helper) |
| , m_bytesAllocated(0) |
| , m_didRecordDrawCommand(false) |
| , m_surfaceIsValid(true) |
| @@ -82,6 +65,15 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, |
| , m_prev(0) |
| , m_lastImageId(0) |
| { |
| + ASSERT(success); |
| + m_context = m_helper->getContext(); |
| + SkAutoTUnref<SkSurface> surface(m_helper->createSurface(m_context.get(), size)); |
| + if (!surface.get()) { |
| + *success = false; |
| + return; |
| + } |
| + m_canvas = new SkDeferredCanvas(surface); |
| + |
| ASSERT(m_canvas); |
| // Used by browser tests to detect the use of a Canvas2DLayerBridge. |
| TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| @@ -91,6 +83,7 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, |
| GraphicsLayer::registerContentsLayer(m_layer->layer()); |
| m_layer->setRateLimitContext(m_rateLimitingEnabled); |
| m_canvas->setNotificationClient(this); |
| + *success = true; |
| } |
| Canvas2DLayerBridge::~Canvas2DLayerBridge() |
| @@ -196,13 +189,13 @@ bool Canvas2DLayerBridge::isValid() |
| // Attempt to recover. |
| m_layer->clearTexture(); |
| m_mailboxes.clear(); |
| - RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get(); |
| + RefPtr<GraphicsContext3D> sharedContext = m_helper->getContext(); |
| if (!sharedContext || sharedContext->webContext()->isContextLost()) { |
| m_surfaceIsValid = false; |
| } else { |
| m_context = sharedContext; |
| IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevice()->height()); |
| - SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size)); |
| + SkAutoTUnref<SkSurface> surface(m_helper->createSurface(m_context.get(), size)); |
| if (surface.get()) { |
| m_canvas->setSurface(surface.get()); |
| m_surfaceIsValid = true; |
| @@ -249,33 +242,37 @@ bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outM |
| return false; |
| m_lastImageId = image->uniqueID(); |
| - mailboxInfo = createMailboxInfo(); |
| - mailboxInfo->m_status = MailboxInUse; |
| - mailboxInfo->m_image.swap(&image); |
| - // Because of texture sharing with the compositor, we must invalidate |
| - // the state cached in skia so that the deferred copy on write |
| - // in SkSurface_Gpu does not make any false assumptions. |
| - mailboxInfo->m_image->getTexture()->invalidateCachedState(); |
| - |
| - ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); |
| - ASSERT(mailboxInfo->m_image.get()); |
| - ASSERT(mailboxInfo->m_image->getTexture()); |
| - |
| - m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_image->getTexture()->getTextureHandle()); |
| - m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); |
| - m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); |
| - m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); |
| - m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); |
| - context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_mailbox.name); |
| - context()->flush(); |
| - mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); |
| - m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); |
| - // Because we are changing the texture binding without going through skia, |
| - // we must dirty the context. |
| - m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); |
| - |
| - *outMailbox = mailboxInfo->m_mailbox; |
| - return true; |
| + GrTexture* texture = image->getTexture(); |
| + if (texture) { |
|
jamesr
2013/08/05 22:56:36
early return on failure would make this function a
|
| + mailboxInfo = createMailboxInfo(); |
| + mailboxInfo->m_status = MailboxInUse; |
| + mailboxInfo->m_image.swap(&image); |
| + // Because of texture sharing with the compositor, we must invalidate |
| + // the state cached in skia so that the deferred copy on write |
| + // in SkSurface_Gpu does not make any false assumptions. |
| + texture->invalidateCachedState(); |
| + |
| + ASSERT(!mailboxInfo->m_mailbox.syncPoint); |
| + ASSERT(mailboxInfo->m_image.get()); |
| + |
| + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture->getTextureHandle()); |
| + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); |
| + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); |
| + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); |
| + m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); |
| + context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_mailbox.name); |
| + context()->flush(); |
| + mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); |
| + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); |
| + // Because we are changing the texture binding without going through skia, |
| + // we must dirty the context. |
| + m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); |
| + *outMailbox = mailboxInfo->m_mailbox; |
| + return true; |
| + } |
| + // TODO: Perform texture upload for cases where image is in RAM. Required for crbug.com/265849 |
| + |
| + return false; |
| } |
| Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() { |