| 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 26 matching lines...) Expand all Loading... |
| 37 #include "core/platform/graphics/gpu/SharedGraphicsContext3D.h" | 37 #include "core/platform/graphics/gpu/SharedGraphicsContext3D.h" |
| 38 #include "public/platform/Platform.h" | 38 #include "public/platform/Platform.h" |
| 39 #include "public/platform/WebCompositorSupport.h" | 39 #include "public/platform/WebCompositorSupport.h" |
| 40 #include "public/platform/WebGraphicsContext3D.h" | 40 #include "public/platform/WebGraphicsContext3D.h" |
| 41 | 41 |
| 42 using WebKit::WebExternalTextureLayer; | 42 using WebKit::WebExternalTextureLayer; |
| 43 using WebKit::WebGraphicsContext3D; | 43 using WebKit::WebGraphicsContext3D; |
| 44 | 44 |
| 45 namespace WebCore { | 45 namespace WebCore { |
| 46 | 46 |
| 47 static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& siz
e) | 47 PassOwnPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassOwnPtr<Helper> h
elper, const IntSize& size, OpacityMode opacityMode) |
| 48 { | |
| 49 ASSERT(!context3D->webContext()->isContextLost()); | |
| 50 GrContext* gr = context3D->grContext(); | |
| 51 if (!gr) | |
| 52 return 0; | |
| 53 gr->resetContext(); | |
| 54 SkImage::Info info; | |
| 55 info.fWidth = size.width(); | |
| 56 info.fHeight = size.height(); | |
| 57 info.fColorType = SkImage::kPMColor_ColorType; | |
| 58 info.fAlphaType = SkImage::kPremul_AlphaType; | |
| 59 return SkSurface::NewRenderTarget(gr, info); | |
| 60 } | |
| 61 | |
| 62 PassOwnPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassRefPtr<GraphicsC
ontext3D> context, const IntSize& size, OpacityMode opacityMode) | |
| 63 { | 48 { |
| 64 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 49 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| 65 SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size)); | 50 bool success; |
| 66 if (!surface.get()) | 51 OwnPtr<Canvas2DLayerBridge> layerBridge = adoptPtr(new Canvas2DLayerBridge(h
elper, size, opacityMode, &success)); |
| 67 return PassOwnPtr<Canvas2DLayerBridge>(); | 52 if (!success) |
| 68 SkDeferredCanvas* canvas = new SkDeferredCanvas(surface); | 53 layerBridge.clear(); |
| 69 OwnPtr<Canvas2DLayerBridge> layerBridge = adoptPtr(new Canvas2DLayerBridge(c
ontext, canvas, opacityMode)); | |
| 70 return layerBridge.release(); | 54 return layerBridge.release(); |
| 71 } | 55 } |
| 72 | 56 |
| 73 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context,
SkDeferredCanvas* canvas, OpacityMode opacityMode) | 57 Canvas2DLayerBridge::Canvas2DLayerBridge(PassOwnPtr<Helper> helper, const IntSiz
e& size, OpacityMode opacityMode, bool* success) |
| 74 : m_canvas(canvas) | 58 : m_helper(helper) |
| 75 , m_context(context) | |
| 76 , m_bytesAllocated(0) | 59 , m_bytesAllocated(0) |
| 77 , m_didRecordDrawCommand(false) | 60 , m_didRecordDrawCommand(false) |
| 78 , m_surfaceIsValid(true) | 61 , m_surfaceIsValid(true) |
| 79 , m_framesPending(0) | 62 , m_framesPending(0) |
| 80 , m_rateLimitingEnabled(false) | 63 , m_rateLimitingEnabled(false) |
| 81 , m_next(0) | 64 , m_next(0) |
| 82 , m_prev(0) | 65 , m_prev(0) |
| 83 , m_lastImageId(0) | 66 , m_lastImageId(0) |
| 84 { | 67 { |
| 68 ASSERT(success); |
| 69 m_context = m_helper->getContext(); |
| 70 SkAutoTUnref<SkSurface> surface(m_helper->createSurface(m_context.get(), siz
e)); |
| 71 if (!surface.get()) { |
| 72 *success = false; |
| 73 return; |
| 74 } |
| 75 m_canvas = new SkDeferredCanvas(surface); |
| 76 |
| 85 ASSERT(m_canvas); | 77 ASSERT(m_canvas); |
| 86 // Used by browser tests to detect the use of a Canvas2DLayerBridge. | 78 // Used by browser tests to detect the use of a Canvas2DLayerBridge. |
| 87 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 79 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| 88 m_layer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createE
xternalTextureLayer(this)); | 80 m_layer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createE
xternalTextureLayer(this)); |
| 89 m_layer->setOpaque(opacityMode == Opaque); | 81 m_layer->setOpaque(opacityMode == Opaque); |
| 90 m_layer->setBlendBackgroundColor(opacityMode != Opaque); | 82 m_layer->setBlendBackgroundColor(opacityMode != Opaque); |
| 91 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 83 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
| 92 m_layer->setRateLimitContext(m_rateLimitingEnabled); | 84 m_layer->setRateLimitContext(m_rateLimitingEnabled); |
| 93 m_canvas->setNotificationClient(this); | 85 m_canvas->setNotificationClient(this); |
| 86 *success = true; |
| 94 } | 87 } |
| 95 | 88 |
| 96 Canvas2DLayerBridge::~Canvas2DLayerBridge() | 89 Canvas2DLayerBridge::~Canvas2DLayerBridge() |
| 97 { | 90 { |
| 98 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 91 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 99 Canvas2DLayerManager::get().layerToBeDestroyed(this); | 92 Canvas2DLayerManager::get().layerToBeDestroyed(this); |
| 100 m_canvas->setNotificationClient(0); | 93 m_canvas->setNotificationClient(0); |
| 101 m_mailboxes.clear(); | 94 m_mailboxes.clear(); |
| 102 m_layer->clearTexture(); | 95 m_layer->clearTexture(); |
| 103 m_layer.clear(); | 96 m_layer.clear(); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 return m_context->webContext(); | 182 return m_context->webContext(); |
| 190 } | 183 } |
| 191 | 184 |
| 192 bool Canvas2DLayerBridge::isValid() | 185 bool Canvas2DLayerBridge::isValid() |
| 193 { | 186 { |
| 194 ASSERT(m_layer); | 187 ASSERT(m_layer); |
| 195 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { | 188 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { |
| 196 // Attempt to recover. | 189 // Attempt to recover. |
| 197 m_layer->clearTexture(); | 190 m_layer->clearTexture(); |
| 198 m_mailboxes.clear(); | 191 m_mailboxes.clear(); |
| 199 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get()
; | 192 RefPtr<GraphicsContext3D> sharedContext = m_helper->getContext(); |
| 200 if (!sharedContext || sharedContext->webContext()->isContextLost()) { | 193 if (!sharedContext || sharedContext->webContext()->isContextLost()) { |
| 201 m_surfaceIsValid = false; | 194 m_surfaceIsValid = false; |
| 202 } else { | 195 } else { |
| 203 m_context = sharedContext; | 196 m_context = sharedContext; |
| 204 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi
ce()->height()); | 197 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi
ce()->height()); |
| 205 SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size)
); | 198 SkAutoTUnref<SkSurface> surface(m_helper->createSurface(m_context.ge
t(), size)); |
| 206 if (surface.get()) { | 199 if (surface.get()) { |
| 207 m_canvas->setSurface(surface.get()); | 200 m_canvas->setSurface(surface.get()); |
| 208 m_surfaceIsValid = true; | 201 m_surfaceIsValid = true; |
| 209 // FIXME: draw sad canvas picture into new buffer crbug.com/2438
42 | 202 // FIXME: draw sad canvas picture into new buffer crbug.com/2438
42 |
| 210 } else { | 203 } else { |
| 211 // Surface allocation failed. Set m_surfaceIsValid to false to | 204 // Surface allocation failed. Set m_surfaceIsValid to false to |
| 212 // trigger subsequent retry. | 205 // trigger subsequent retry. |
| 213 m_surfaceIsValid = false; | 206 m_surfaceIsValid = false; |
| 214 } | 207 } |
| 215 } | 208 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 242 mailboxInfo->m_image.reset(0); | 235 mailboxInfo->m_image.reset(0); |
| 243 mailboxInfo->m_status = MailboxAvailable; | 236 mailboxInfo->m_status = MailboxAvailable; |
| 244 } | 237 } |
| 245 } | 238 } |
| 246 SkAutoTUnref<SkImage> image(m_canvas->newImageSnapshot()); | 239 SkAutoTUnref<SkImage> image(m_canvas->newImageSnapshot()); |
| 247 // Early exit if canvas was not drawn to since last prepareMailbox | 240 // Early exit if canvas was not drawn to since last prepareMailbox |
| 248 if (image->uniqueID() == m_lastImageId) | 241 if (image->uniqueID() == m_lastImageId) |
| 249 return false; | 242 return false; |
| 250 m_lastImageId = image->uniqueID(); | 243 m_lastImageId = image->uniqueID(); |
| 251 | 244 |
| 245 GrTexture* texture = image->getTexture(); |
| 246 // TODO: Perform texture upload for cases where image is in RAM. Required fo
r crbug.com/265849 |
| 247 if (!texture) |
| 248 return false; |
| 249 |
| 252 mailboxInfo = createMailboxInfo(); | 250 mailboxInfo = createMailboxInfo(); |
| 253 mailboxInfo->m_status = MailboxInUse; | 251 mailboxInfo->m_status = MailboxInUse; |
| 254 mailboxInfo->m_image.swap(&image); | 252 mailboxInfo->m_image.swap(&image); |
| 255 // Because of texture sharing with the compositor, we must invalidate | 253 // Because of texture sharing with the compositor, we must invalidate |
| 256 // the state cached in skia so that the deferred copy on write | 254 // the state cached in skia so that the deferred copy on write |
| 257 // in SkSurface_Gpu does not make any false assumptions. | 255 // in SkSurface_Gpu does not make any false assumptions. |
| 258 mailboxInfo->m_image->getTexture()->invalidateCachedState(); | 256 texture->invalidateCachedState(); |
| 259 | 257 |
| 260 ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); | 258 ASSERT(!mailboxInfo->m_mailbox.syncPoint); |
| 261 ASSERT(mailboxInfo->m_image.get()); | 259 ASSERT(mailboxInfo->m_image.get()); |
| 262 ASSERT(mailboxInfo->m_image->getTexture()); | |
| 263 | 260 |
| 264 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_image->
getTexture()->getTextureHandle()); | 261 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture->getTextureHan
dle()); |
| 265 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); | 262 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); |
| 266 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); | 263 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); |
| 267 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); | 264 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); |
| 268 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); | 265 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T
EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); |
| 269 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo
->m_mailbox.name); | 266 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo
->m_mailbox.name); |
| 270 context()->flush(); | 267 context()->flush(); |
| 271 mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); | 268 mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); |
| 272 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); | 269 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); |
| 273 // Because we are changing the texture binding without going through skia, | 270 // Because we are changing the texture binding without going through skia, |
| 274 // we must dirty the context. | 271 // we must dirty the context. |
| 275 m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); | 272 m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); |
| 276 | |
| 277 *outMailbox = mailboxInfo->m_mailbox; | 273 *outMailbox = mailboxInfo->m_mailbox; |
| 278 return true; | 274 return true; |
| 279 } | 275 } |
| 280 | 276 |
| 281 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() { | 277 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() { |
| 282 MailboxInfo* mailboxInfo; | 278 MailboxInfo* mailboxInfo; |
| 283 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai
lboxInfo++) { | 279 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai
lboxInfo++) { |
| 284 if (mailboxInfo->m_status == MailboxAvailable) { | 280 if (mailboxInfo->m_status == MailboxAvailable) { |
| 285 return mailboxInfo; | 281 return mailboxInfo; |
| 286 } | 282 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { | 339 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { |
| 344 // This copy constructor should only be used for Vector reallocation | 340 // This copy constructor should only be used for Vector reallocation |
| 345 // Assuming 'other' is to be destroyed, we swap m_image ownership | 341 // Assuming 'other' is to be destroyed, we swap m_image ownership |
| 346 // rather than do a refcount dance. | 342 // rather than do a refcount dance. |
| 347 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); | 343 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); |
| 348 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); | 344 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); |
| 349 m_status = other.m_status; | 345 m_status = other.m_status; |
| 350 } | 346 } |
| 351 | 347 |
| 352 } | 348 } |
| OLD | NEW |