Chromium Code Reviews| 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 void Canvas2DLayerBridgePtr::clear() | |
| 48 { | |
| 49 if (m_ptr) { | |
| 50 m_ptr->destroy(); | |
| 51 m_ptr.clear(); | |
|
Stephen White
2013/08/23 14:45:28
MicroNit: This is probably redundant, since we'll
| |
| 52 } | |
| 53 } | |
| 54 | |
| 55 Canvas2DLayerBridgePtr::Canvas2DLayerBridgePtr(const Canvas2DLayerBridgePtr& oth er) | |
| 56 { | |
| 57 *this = other; | |
| 58 } | |
| 59 | |
| 60 Canvas2DLayerBridgePtr& Canvas2DLayerBridgePtr::operator=(const Canvas2DLayerBri dgePtr& other) | |
| 61 { | |
| 62 m_ptr = other.m_ptr; | |
| 63 const_cast<Canvas2DLayerBridgePtr*>(&other)->m_ptr.clear(); // transfer of o wnership | |
|
Stephen White
2013/08/23 14:45:28
Hmm. I wonder if you could have a private const cl
| |
| 64 return *this; | |
| 65 } | |
| 66 | |
| 47 static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& siz e) | 67 static SkSurface* createSurface(GraphicsContext3D* context3D, const IntSize& siz e) |
| 48 { | 68 { |
| 49 ASSERT(!context3D->webContext()->isContextLost()); | 69 ASSERT(!context3D->webContext()->isContextLost()); |
| 50 GrContext* gr = context3D->grContext(); | 70 GrContext* gr = context3D->grContext(); |
| 51 if (!gr) | 71 if (!gr) |
| 52 return 0; | 72 return 0; |
| 53 gr->resetContext(); | 73 gr->resetContext(); |
| 54 SkImage::Info info; | 74 SkImage::Info info; |
| 55 info.fWidth = size.width(); | 75 info.fWidth = size.width(); |
| 56 info.fHeight = size.height(); | 76 info.fHeight = size.height(); |
| 57 info.fColorType = SkImage::kPMColor_ColorType; | 77 info.fColorType = SkImage::kPMColor_ColorType; |
| 58 info.fAlphaType = SkImage::kPremul_AlphaType; | 78 info.fAlphaType = SkImage::kPremul_AlphaType; |
| 59 return SkSurface::NewRenderTarget(gr, info); | 79 return SkSurface::NewRenderTarget(gr, info); |
| 60 } | 80 } |
| 61 | 81 |
| 62 PassOwnPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(PassRefPtr<GraphicsC ontext3D> context, const IntSize& size, OpacityMode opacityMode) | 82 Canvas2DLayerBridgePtr Canvas2DLayerBridge::create(PassRefPtr<GraphicsContext3D> context, const IntSize& size, OpacityMode opacityMode) |
| 63 { | 83 { |
| 64 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 84 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| 65 SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size)); | 85 SkAutoTUnref<SkSurface> surface(createSurface(context.get(), size)); |
| 66 if (!surface.get()) | 86 if (!surface.get()) { |
| 67 return PassOwnPtr<Canvas2DLayerBridge>(); | 87 Canvas2DLayerBridgePtr result; |
| 88 return result; | |
| 89 } | |
| 68 SkDeferredCanvas* canvas = SkDeferredCanvas::Create(surface.get()); | 90 SkDeferredCanvas* canvas = SkDeferredCanvas::Create(surface.get()); |
| 69 OwnPtr<Canvas2DLayerBridge> layerBridge = adoptPtr(new Canvas2DLayerBridge(c ontext, canvas, opacityMode)); | 91 RefPtr<Canvas2DLayerBridge> layerBridge = adoptRef(new Canvas2DLayerBridge(c ontext, canvas, opacityMode)); |
| 70 return layerBridge.release(); | 92 Canvas2DLayerBridgePtr result(layerBridge.release()); |
| 93 return result; | |
| 71 } | 94 } |
| 72 | 95 |
| 73 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, SkDeferredCanvas* canvas, OpacityMode opacityMode) | 96 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, SkDeferredCanvas* canvas, OpacityMode opacityMode) |
| 74 : m_canvas(canvas) | 97 : m_canvas(canvas) |
| 75 , m_context(context) | 98 , m_context(context) |
| 76 , m_bytesAllocated(0) | 99 , m_bytesAllocated(0) |
| 77 , m_didRecordDrawCommand(false) | 100 , m_didRecordDrawCommand(false) |
| 78 , m_surfaceIsValid(true) | 101 , m_surfaceIsValid(true) |
| 79 , m_framesPending(0) | 102 , m_framesPending(0) |
| 103 , m_liveMailboxCount(0) | |
| 104 , m_destructionInProgress(false) | |
| 80 , m_rateLimitingEnabled(false) | 105 , m_rateLimitingEnabled(false) |
| 81 , m_next(0) | 106 , m_next(0) |
| 82 , m_prev(0) | 107 , m_prev(0) |
| 83 , m_lastImageId(0) | 108 , m_lastImageId(0) |
| 84 { | 109 { |
| 85 ASSERT(m_canvas); | 110 ASSERT(m_canvas); |
| 86 // Used by browser tests to detect the use of a Canvas2DLayerBridge. | 111 // Used by browser tests to detect the use of a Canvas2DLayerBridge. |
| 87 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 112 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
| 88 m_layer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createE xternalTextureLayer(this)); | 113 m_layer = adoptPtr(WebKit::Platform::current()->compositorSupport()->createE xternalTextureLayer(this)); |
| 89 m_layer->setOpaque(opacityMode == Opaque); | 114 m_layer->setOpaque(opacityMode == Opaque); |
| 90 m_layer->setBlendBackgroundColor(opacityMode != Opaque); | 115 m_layer->setBlendBackgroundColor(opacityMode != Opaque); |
| 91 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 116 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
| 92 m_layer->setRateLimitContext(m_rateLimitingEnabled); | 117 m_layer->setRateLimitContext(m_rateLimitingEnabled); |
| 93 m_canvas->setNotificationClient(this); | 118 m_canvas->setNotificationClient(this); |
| 94 } | 119 } |
| 95 | 120 |
| 96 Canvas2DLayerBridge::~Canvas2DLayerBridge() | 121 Canvas2DLayerBridge::~Canvas2DLayerBridge() |
| 97 { | 122 { |
| 123 ASSERT(m_destructionInProgress); | |
| 124 m_layer.clear(); | |
| 125 Vector<MailboxInfo>::iterator mailboxInfo; | |
| 126 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | |
| 127 ASSERT(mailboxInfo->m_status != MailboxInUse); | |
| 128 if (mailboxInfo->m_status == MailboxReleased) { | |
| 129 if (mailboxInfo->m_mailbox.syncPoint) { | |
| 130 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); | |
| 131 mailboxInfo->m_mailbox.syncPoint = 0; | |
| 132 } | |
| 133 // Invalidate texture state in case the compositor altered it since the copy-on-write. | |
| 134 mailboxInfo->m_image->getTexture()->invalidateCachedState(); | |
| 135 } | |
| 136 } | |
| 137 m_mailboxes.clear(); | |
| 138 } | |
| 139 | |
| 140 void Canvas2DLayerBridge::destroy() | |
| 141 { | |
| 142 ASSERT(!m_destructionInProgress); | |
| 143 m_destructionInProgress = true; | |
| 98 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 144 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 145 m_canvas->setNotificationClient(0); | |
| 146 m_layer->clearTexture(); | |
| 99 Canvas2DLayerManager::get().layerToBeDestroyed(this); | 147 Canvas2DLayerManager::get().layerToBeDestroyed(this); |
| 100 m_canvas->setNotificationClient(0); | |
| 101 m_mailboxes.clear(); | |
| 102 m_layer->clearTexture(); | |
| 103 m_layer.clear(); | |
| 104 } | 148 } |
| 105 | 149 |
| 106 void Canvas2DLayerBridge::limitPendingFrames() | 150 void Canvas2DLayerBridge::limitPendingFrames() |
| 107 { | 151 { |
| 152 ASSERT(!m_destructionInProgress); | |
| 108 if (m_didRecordDrawCommand) { | 153 if (m_didRecordDrawCommand) { |
| 109 m_framesPending++; | 154 m_framesPending++; |
| 110 m_didRecordDrawCommand = false; | 155 m_didRecordDrawCommand = false; |
| 111 if (m_framesPending > 1) { | 156 if (m_framesPending > 1) { |
| 112 // Turn on the rate limiter if this layer tends to accumulate a | 157 // Turn on the rate limiter if this layer tends to accumulate a |
| 113 // non-discardable multi-frame backlog of draw commands. | 158 // non-discardable multi-frame backlog of draw commands. |
| 114 setRateLimitingEnabled(true); | 159 setRateLimitingEnabled(true); |
| 115 } | 160 } |
| 116 if (m_rateLimitingEnabled) { | 161 if (m_rateLimitingEnabled) { |
| 117 flush(); | 162 flush(); |
| 118 } | 163 } |
| 119 } | 164 } |
| 120 } | 165 } |
| 121 | 166 |
| 122 void Canvas2DLayerBridge::prepareForDraw() | 167 void Canvas2DLayerBridge::prepareForDraw() |
| 123 { | 168 { |
| 169 ASSERT(!m_destructionInProgress); | |
| 124 ASSERT(m_layer); | 170 ASSERT(m_layer); |
| 125 if (!isValid()) { | 171 if (!isValid()) { |
| 126 if (m_canvas) { | 172 if (m_canvas) { |
| 127 // drop pending commands because there is no surface to draw to | 173 // drop pending commands because there is no surface to draw to |
| 128 m_canvas->silentFlush(); | 174 m_canvas->silentFlush(); |
| 129 } | 175 } |
| 130 return; | 176 return; |
| 131 } | 177 } |
| 132 m_context->makeContextCurrent(); | 178 m_context->makeContextCurrent(); |
| 133 } | 179 } |
| 134 | 180 |
| 135 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted) | 181 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted) |
| 136 { | 182 { |
| 183 ASSERT(!m_destructionInProgress); | |
| 137 intptr_t delta = (intptr_t)bytesAllocated - (intptr_t)m_bytesAllocated; | 184 intptr_t delta = (intptr_t)bytesAllocated - (intptr_t)m_bytesAllocated; |
| 138 m_bytesAllocated = bytesAllocated; | 185 m_bytesAllocated = bytesAllocated; |
| 139 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, delta); | 186 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, delta); |
| 140 } | 187 } |
| 141 | 188 |
| 142 size_t Canvas2DLayerBridge::storageAllocatedForRecording() | 189 size_t Canvas2DLayerBridge::storageAllocatedForRecording() |
| 143 { | 190 { |
| 191 ASSERT(!m_destructionInProgress); | |
| 144 return m_canvas->storageAllocatedForRecording(); | 192 return m_canvas->storageAllocatedForRecording(); |
| 145 } | 193 } |
| 146 | 194 |
| 147 void Canvas2DLayerBridge::flushedDrawCommands() | 195 void Canvas2DLayerBridge::flushedDrawCommands() |
| 148 { | 196 { |
| 197 ASSERT(!m_destructionInProgress); | |
| 149 storageAllocatedForRecordingChanged(storageAllocatedForRecording()); | 198 storageAllocatedForRecordingChanged(storageAllocatedForRecording()); |
| 150 m_framesPending = 0; | 199 m_framesPending = 0; |
| 151 } | 200 } |
| 152 | 201 |
| 153 void Canvas2DLayerBridge::skippedPendingDrawCommands() | 202 void Canvas2DLayerBridge::skippedPendingDrawCommands() |
| 154 { | 203 { |
| 204 ASSERT(!m_destructionInProgress); | |
| 155 // Stop triggering the rate limiter if SkDeferredCanvas is detecting | 205 // Stop triggering the rate limiter if SkDeferredCanvas is detecting |
| 156 // and optimizing overdraw. | 206 // and optimizing overdraw. |
| 157 setRateLimitingEnabled(false); | 207 setRateLimitingEnabled(false); |
| 158 flushedDrawCommands(); | 208 flushedDrawCommands(); |
| 159 } | 209 } |
| 160 | 210 |
| 161 void Canvas2DLayerBridge::setRateLimitingEnabled(bool enabled) | 211 void Canvas2DLayerBridge::setRateLimitingEnabled(bool enabled) |
| 162 { | 212 { |
| 213 ASSERT(!m_destructionInProgress || !enabled); | |
| 163 if (m_rateLimitingEnabled != enabled) { | 214 if (m_rateLimitingEnabled != enabled) { |
| 164 m_rateLimitingEnabled = enabled; | 215 m_rateLimitingEnabled = enabled; |
| 165 m_layer->setRateLimitContext(m_rateLimitingEnabled); | 216 m_layer->setRateLimitContext(m_rateLimitingEnabled); |
| 166 } | 217 } |
| 167 } | 218 } |
| 168 | 219 |
| 169 size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree) | 220 size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree) |
| 170 { | 221 { |
| 222 ASSERT(!m_destructionInProgress); | |
| 171 size_t bytesFreed = m_canvas->freeMemoryIfPossible(bytesToFree); | 223 size_t bytesFreed = m_canvas->freeMemoryIfPossible(bytesToFree); |
| 172 if (bytesFreed) | 224 if (bytesFreed) |
| 173 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((intptr _t)bytesFreed)); | 225 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((intptr _t)bytesFreed)); |
| 174 m_bytesAllocated -= bytesFreed; | 226 m_bytesAllocated -= bytesFreed; |
| 175 return bytesFreed; | 227 return bytesFreed; |
| 176 } | 228 } |
| 177 | 229 |
| 178 void Canvas2DLayerBridge::flush() | 230 void Canvas2DLayerBridge::flush() |
| 179 { | 231 { |
| 232 ASSERT(!m_destructionInProgress); | |
| 180 if (m_canvas->hasPendingCommands()) { | 233 if (m_canvas->hasPendingCommands()) { |
| 181 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); | 234 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); |
| 182 m_canvas->flush(); | 235 m_canvas->flush(); |
| 183 } | 236 } |
| 184 } | 237 } |
| 185 | 238 |
| 186 WebGraphicsContext3D* Canvas2DLayerBridge::context() | 239 WebGraphicsContext3D* Canvas2DLayerBridge::context() |
| 187 { | 240 { |
| 188 // Check on m_layer is necessary because context() may be called during | 241 // Check on m_layer is necessary because context() may be called during |
| 189 // the destruction of m_layer | 242 // the destruction of m_layer |
| 190 if (m_layer) { | 243 if (m_layer) { |
| 191 isValid(); // To ensure rate limiter is disabled if context is lost. | 244 isValid(); // To ensure rate limiter is disabled if context is lost. |
| 192 } | 245 } |
| 193 return m_context->webContext(); | 246 return m_context->webContext(); |
| 194 } | 247 } |
| 195 | 248 |
| 196 bool Canvas2DLayerBridge::isValid() | 249 bool Canvas2DLayerBridge::isValid() |
| 197 { | 250 { |
| 198 ASSERT(m_layer); | 251 ASSERT(m_layer); |
| 252 if (m_destructionInProgress) | |
| 253 return false; | |
| 199 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { | 254 if (m_context->webContext()->isContextLost() || !m_surfaceIsValid) { |
| 200 // Attempt to recover. | 255 // Attempt to recover. |
| 201 m_layer->clearTexture(); | 256 m_layer->clearTexture(); |
| 202 m_mailboxes.clear(); | 257 m_mailboxes.clear(); |
| 203 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get() ; | 258 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get() ; |
| 204 if (!sharedContext || sharedContext->webContext()->isContextLost()) { | 259 if (!sharedContext || sharedContext->webContext()->isContextLost()) { |
| 205 m_surfaceIsValid = false; | 260 m_surfaceIsValid = false; |
| 206 } else { | 261 } else { |
| 207 m_context = sharedContext; | 262 m_context = sharedContext; |
| 208 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi ce()->height()); | 263 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevi ce()->height()); |
| 209 SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size) ); | 264 SkAutoTUnref<SkSurface> surface(createSurface(m_context.get(), size) ); |
| 210 if (surface.get()) { | 265 if (surface.get()) { |
| 211 m_canvas->setSurface(surface.get()); | 266 m_canvas->setSurface(surface.get()); |
| 212 m_surfaceIsValid = true; | 267 m_surfaceIsValid = true; |
| 213 // FIXME: draw sad canvas picture into new buffer crbug.com/2438 42 | 268 // FIXME: draw sad canvas picture into new buffer crbug.com/2438 42 |
| 214 } else { | 269 } else { |
| 215 // Surface allocation failed. Set m_surfaceIsValid to false to | 270 // Surface allocation failed. Set m_surfaceIsValid to false to |
| 216 // trigger subsequent retry. | 271 // trigger subsequent retry. |
| 217 m_surfaceIsValid = false; | 272 m_surfaceIsValid = false; |
| 218 } | 273 } |
| 219 } | 274 } |
| 220 } | 275 } |
| 221 if (!m_surfaceIsValid) | 276 if (!m_surfaceIsValid) |
| 222 setRateLimitingEnabled(false); | 277 setRateLimitingEnabled(false); |
| 223 return m_surfaceIsValid; | 278 return m_surfaceIsValid; |
| 224 | |
| 225 } | 279 } |
| 226 | 280 |
| 227 bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outM ailbox, WebKit::WebExternalBitmap* bitmap) | 281 bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outM ailbox, WebKit::WebExternalBitmap* bitmap) |
| 228 { | 282 { |
| 283 if (m_destructionInProgress) { | |
| 284 const WebKit::WebExternalTextureMailbox emptyMailbox; | |
| 285 *outMailbox = emptyMailbox; | |
| 286 return true; | |
| 287 } | |
| 229 ASSERT(!bitmap); | 288 ASSERT(!bitmap); |
| 230 if (!isValid()) | 289 if (!isValid()) |
| 231 return false; | 290 return false; |
| 232 // Release to skia textures that were previouosly released by the | 291 // Release to skia textures that were previouosly released by the |
| 233 // compositor. We do this before acquiring the next snapshot in | 292 // compositor. We do this before acquiring the next snapshot in |
| 234 // order to cap maximum gpu memory consumption. | 293 // order to cap maximum gpu memory consumption. |
| 235 m_context->makeContextCurrent(); | 294 m_context->makeContextCurrent(); |
| 236 flush(); | 295 flush(); |
| 237 Vector<MailboxInfo>::iterator mailboxInfo; | 296 Vector<MailboxInfo>::iterator mailboxInfo; |
| 238 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | 297 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); | 330 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); |
| 272 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); | 331 m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::T EXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); |
| 273 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo ->m_mailbox.name); | 332 context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo ->m_mailbox.name); |
| 274 context()->flush(); | 333 context()->flush(); |
| 275 mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); | 334 mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); |
| 276 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); | 335 m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); |
| 277 // Because we are changing the texture binding without going through skia, | 336 // Because we are changing the texture binding without going through skia, |
| 278 // we must dirty the context. | 337 // we must dirty the context. |
| 279 m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); | 338 m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); |
| 280 | 339 |
| 340 // set m_parentLayerBridge to make sure 'this' stays alive as long as it has | |
| 341 // live mailboxes | |
| 342 ASSERT(!mailboxInfo->m_parentLayerBridge); | |
| 343 this->ref(); // Because we are adopting an already referenced object | |
| 344 mailboxInfo->m_parentLayerBridge = adoptRef(this); | |
| 345 m_liveMailboxCount++; | |
|
Stephen White
2013/08/23 14:45:28
m_liveMailboxCount seems to be only written now, a
| |
| 281 *outMailbox = mailboxInfo->m_mailbox; | 346 *outMailbox = mailboxInfo->m_mailbox; |
| 282 return true; | 347 return true; |
| 283 } | 348 } |
| 284 | 349 |
| 285 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() { | 350 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() { |
| 351 ASSERT(!m_destructionInProgress); | |
| 286 MailboxInfo* mailboxInfo; | 352 MailboxInfo* mailboxInfo; |
| 287 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | 353 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { |
| 288 if (mailboxInfo->m_status == MailboxAvailable) { | 354 if (mailboxInfo->m_status == MailboxAvailable) { |
| 289 return mailboxInfo; | 355 return mailboxInfo; |
| 290 } | 356 } |
| 291 } | 357 } |
| 292 | 358 |
| 293 // No available mailbox: create one. | 359 // No available mailbox: create one. |
| 294 m_mailboxes.grow(m_mailboxes.size() + 1); | 360 m_mailboxes.grow(m_mailboxes.size() + 1); |
| 295 mailboxInfo = &m_mailboxes.last(); | 361 mailboxInfo = &m_mailboxes.last(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 306 } | 372 } |
| 307 | 373 |
| 308 void Canvas2DLayerBridge::mailboxReleased(const WebKit::WebExternalTextureMailbo x& mailbox) | 374 void Canvas2DLayerBridge::mailboxReleased(const WebKit::WebExternalTextureMailbo x& mailbox) |
| 309 { | 375 { |
| 310 Vector<MailboxInfo>::iterator mailboxInfo; | 376 Vector<MailboxInfo>::iterator mailboxInfo; |
| 311 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | 377 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { |
| 312 if (!memcmp(mailboxInfo->m_mailbox.name, mailbox.name, sizeof(mailbox.na me))) { | 378 if (!memcmp(mailboxInfo->m_mailbox.name, mailbox.name, sizeof(mailbox.na me))) { |
| 313 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint; | 379 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint; |
| 314 ASSERT(mailboxInfo->m_status == MailboxInUse); | 380 ASSERT(mailboxInfo->m_status == MailboxInUse); |
| 315 mailboxInfo->m_status = MailboxReleased; | 381 mailboxInfo->m_status = MailboxReleased; |
| 382 // Trigger Canvas2DLayerBridge self-destruction if this is the | |
| 383 // last live mailbox and the layer bridge is not externally | |
| 384 // referenced. | |
| 385 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this); | |
| 386 m_liveMailboxCount--; | |
| 387 mailboxInfo->m_parentLayerBridge.clear(); | |
| 316 return; | 388 return; |
| 317 } | 389 } |
| 318 } | 390 } |
| 319 } | 391 } |
| 320 | 392 |
| 321 WebKit::WebLayer* Canvas2DLayerBridge::layer() | 393 WebKit::WebLayer* Canvas2DLayerBridge::layer() |
| 322 { | 394 { |
| 323 ASSERT(m_layer); | 395 ASSERT(m_layer); |
| 324 return m_layer->layer(); | 396 return m_layer->layer(); |
| 325 } | 397 } |
| 326 | 398 |
| 327 void Canvas2DLayerBridge::contextAcquired() | 399 void Canvas2DLayerBridge::contextAcquired() |
| 328 { | 400 { |
| 401 ASSERT(!m_destructionInProgress); | |
| 329 Canvas2DLayerManager::get().layerDidDraw(this); | 402 Canvas2DLayerManager::get().layerDidDraw(this); |
| 330 m_didRecordDrawCommand = true; | 403 m_didRecordDrawCommand = true; |
| 331 } | 404 } |
| 332 | 405 |
| 333 unsigned Canvas2DLayerBridge::backBufferTexture() | 406 unsigned Canvas2DLayerBridge::backBufferTexture() |
| 334 { | 407 { |
| 408 ASSERT(!m_destructionInProgress); | |
| 335 if (!isValid()) | 409 if (!isValid()) |
| 336 return 0; | 410 return 0; |
| 337 contextAcquired(); | 411 contextAcquired(); |
| 338 m_canvas->flush(); | 412 m_canvas->flush(); |
| 339 m_context->flush(); | 413 m_context->flush(); |
| 340 GrRenderTarget* renderTarget = reinterpret_cast<GrRenderTarget*>(m_canvas->g etDevice()->accessRenderTarget()); | 414 GrRenderTarget* renderTarget = reinterpret_cast<GrRenderTarget*>(m_canvas->g etDevice()->accessRenderTarget()); |
| 341 if (renderTarget) { | 415 if (renderTarget) { |
| 342 return renderTarget->asTexture()->getTextureHandle(); | 416 return renderTarget->asTexture()->getTextureHandle(); |
| 343 } | 417 } |
| 344 return 0; | 418 return 0; |
| 345 } | 419 } |
| 346 | 420 |
| 347 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { | 421 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { |
| 348 // This copy constructor should only be used for Vector reallocation | 422 // This copy constructor should only be used for Vector reallocation |
| 349 // Assuming 'other' is to be destroyed, we swap m_image ownership | 423 // Assuming 'other' is to be destroyed, we swap m_image ownership |
| 350 // rather than do a refcount dance. | 424 // rather than do a refcount dance. |
| 351 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); | 425 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); |
| 352 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); | 426 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); |
| 353 m_status = other.m_status; | 427 m_status = other.m_status; |
| 354 } | 428 } |
| 355 | 429 |
| 356 } | 430 } |
| OLD | NEW |