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 23 matching lines...) Expand all Loading... | |
34 #include "platform/graphics/Canvas2DLayerManager.h" | 34 #include "platform/graphics/Canvas2DLayerManager.h" |
35 #include "platform/graphics/GraphicsLayer.h" | 35 #include "platform/graphics/GraphicsLayer.h" |
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 { | |
45 const size_t MaxSize = ~static_cast<size_t>(0); | |
eseidel
2013/12/19 02:56:32
std::limits?
| |
46 } | |
47 | |
44 namespace WebCore { | 48 namespace WebCore { |
45 | 49 |
46 static PassRefPtr<SkSurface> createSkSurface(GraphicsContext3D* context3D, const IntSize& size, int msaaSampleCount) | 50 static PassRefPtr<SkSurface> createSkSurface(GraphicsContext3D* context3D, const IntSize& size, int msaaSampleCount) |
47 { | 51 { |
48 ASSERT(!context3D->webContext()->isContextLost()); | 52 ASSERT(!context3D->webContext()->isContextLost()); |
49 GrContext* gr = context3D->grContext(); | 53 GrContext* gr = context3D->grContext(); |
50 if (!gr) | 54 if (!gr) |
51 return 0; | 55 return 0; |
52 gr->resetContext(); | 56 gr->resetContext(); |
53 SkImageInfo info; | 57 SkImageInfo info; |
54 info.fWidth = size.width(); | 58 info.fWidth = size.width(); |
55 info.fHeight = size.height(); | 59 info.fHeight = size.height(); |
56 info.fColorType = kPMColor_SkColorType; | 60 info.fColorType = kPMColor_SkColorType; |
57 info.fAlphaType = kPremul_SkAlphaType; | 61 info.fAlphaType = kPremul_SkAlphaType; |
58 return adoptRef(SkSurface::NewRenderTarget(gr, info, msaaSampleCount)); | 62 return adoptRef(SkSurface::NewRenderTarget(gr, info, msaaSampleCount)); |
59 } | 63 } |
60 | 64 |
61 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size, OpacityMode opacityMode, int msaaSampleCount) | 65 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(Canvas2DLayerBridgeC lient* client, const IntSize& size, OpacityMode opacityMode, int msaaSampleCount ) |
62 { | 66 { |
63 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 67 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
64 RefPtr<GraphicsContext3D> context = SharedGraphicsContext3D::get(); | 68 RefPtr<GraphicsContext3D> context = SharedGraphicsContext3D::get(); |
65 RefPtr<SkSurface> surface(createSkSurface(context.get(), size, msaaSampleCou nt)); | 69 RefPtr<SkSurface> surface(createSkSurface(context.get(), size, msaaSampleCou nt)); |
66 if (!surface) | 70 if (!surface) |
67 return 0; | 71 return 0; |
68 RefPtr<Canvas2DLayerBridge> layerBridge; | 72 RefPtr<Canvas2DLayerBridge> layerBridge; |
69 OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface. get())); | 73 OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface. get())); |
70 layerBridge = adoptRef(new Canvas2DLayerBridge(context, canvas.release(), ms aaSampleCount, opacityMode)); | 74 layerBridge = adoptRef(new Canvas2DLayerBridge(client, context, canvas.relea se(), msaaSampleCount, opacityMode)); |
71 return layerBridge.release(); | 75 return layerBridge.release(); |
72 } | 76 } |
73 | 77 |
74 Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<SkDeferredCanvas> canvas, int msaaSampleCount, OpacityMode opacityMod e) | 78 Canvas2DLayerBridge::Canvas2DLayerBridge(Canvas2DLayerBridgeClient* client, Pass RefPtr<GraphicsContext3D> context, PassOwnPtr<SkDeferredCanvas> canvas, int msaa SampleCount, OpacityMode opacityMode) |
75 : m_canvas(canvas) | 79 : m_client(client) |
80 , m_canvas(canvas) | |
76 , m_context(context) | 81 , m_context(context) |
77 , m_msaaSampleCount(msaaSampleCount) | 82 , m_msaaSampleCount(msaaSampleCount) |
78 , m_bytesAllocated(0) | 83 , m_bytesAllocated(0) |
79 , m_didRecordDrawCommand(false) | 84 , m_didRecordDrawCommand(false) |
80 , m_surfaceIsValid(true) | 85 , m_surfaceIsValid(true) |
81 , m_framesPending(0) | 86 , m_framesPending(0) |
87 , m_framesSinceMailboxRelease(0) | |
82 , m_destructionInProgress(false) | 88 , m_destructionInProgress(false) |
83 , m_rateLimitingEnabled(false) | 89 , m_rateLimitingEnabled(false) |
84 , m_next(0) | 90 , m_next(0) |
85 , m_prev(0) | 91 , m_prev(0) |
86 , m_lastImageId(0) | 92 , m_lastImageId(0) |
93 , m_releasedMailboxInfo(0) | |
87 { | 94 { |
88 ASSERT(m_canvas); | 95 ASSERT(m_canvas); |
96 ASSERT(m_client); | |
89 // Used by browser tests to detect the use of a Canvas2DLayerBridge. | 97 // Used by browser tests to detect the use of a Canvas2DLayerBridge. |
90 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); | 98 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation"); |
91 m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->createEx ternalTextureLayer(this)); | 99 m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->createEx ternalTextureLayer(this)); |
92 m_layer->setOpaque(opacityMode == Opaque); | 100 m_layer->setOpaque(opacityMode == Opaque); |
93 m_layer->setBlendBackgroundColor(opacityMode != Opaque); | 101 m_layer->setBlendBackgroundColor(opacityMode != Opaque); |
94 GraphicsLayer::registerContentsLayer(m_layer->layer()); | 102 GraphicsLayer::registerContentsLayer(m_layer->layer()); |
95 m_layer->setRateLimitContext(m_rateLimitingEnabled); | 103 m_layer->setRateLimitContext(m_rateLimitingEnabled); |
96 m_canvas->setNotificationClient(this); | 104 m_canvas->setNotificationClient(this); |
97 } | 105 } |
98 | 106 |
99 Canvas2DLayerBridge::~Canvas2DLayerBridge() | 107 Canvas2DLayerBridge::~Canvas2DLayerBridge() |
100 { | 108 { |
101 ASSERT(m_destructionInProgress); | 109 ASSERT(m_destructionInProgress); |
102 m_layer.clear(); | 110 m_layer.clear(); |
111 freeReleasedMailbox(); | |
112 #if !ASSERT_DISABLED | |
103 Vector<MailboxInfo>::iterator mailboxInfo; | 113 Vector<MailboxInfo>::iterator mailboxInfo; |
104 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | 114 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { |
105 ASSERT(mailboxInfo->m_status != MailboxInUse); | 115 ASSERT(mailboxInfo->m_status != MailboxInUse); |
106 if (mailboxInfo->m_status == MailboxReleased) { | 116 ASSERT(mailboxInfo->m_status != MailboxReleased); |
107 if (mailboxInfo->m_mailbox.syncPoint) { | |
108 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); | |
109 mailboxInfo->m_mailbox.syncPoint = 0; | |
110 } | |
111 // Invalidate texture state in case the compositor altered it since the copy-on-write. | |
112 mailboxInfo->m_image->getTexture()->invalidateCachedState(); | |
113 } | |
114 } | 117 } |
118 #endif | |
115 m_mailboxes.clear(); | 119 m_mailboxes.clear(); |
116 } | 120 } |
117 | 121 |
118 void Canvas2DLayerBridge::beginDestruction() | 122 void Canvas2DLayerBridge::beginDestruction() |
119 { | 123 { |
120 ASSERT(!m_destructionInProgress); | 124 ASSERT(!m_destructionInProgress); |
121 m_destructionInProgress = true; | 125 m_destructionInProgress = true; |
122 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 126 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
123 m_canvas->setNotificationClient(0); | 127 m_canvas->setNotificationClient(0); |
124 m_layer->clearTexture(); | 128 m_layer->clearTexture(); |
125 Canvas2DLayerManager::get().layerToBeDestroyed(this); | 129 Canvas2DLayerManager::get().layerToBeDestroyed(this); |
126 // Orphaning the layer is required to trigger the recration of a new layer | 130 // Orphaning the layer is required to trigger the recration of a new layer |
127 // in the case where destruction is caused by a canvas resize. Test: | 131 // in the case where destruction is caused by a canvas resize. Test: |
128 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html | 132 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html |
129 m_layer->layer()->removeFromParent(); | 133 m_layer->layer()->removeFromParent(); |
130 } | 134 } |
131 | 135 |
136 bool Canvas2DLayerBridge::hidden() const | |
137 { | |
138 return m_destructionInProgress || m_client->hidden(); | |
139 } | |
140 | |
141 void Canvas2DLayerBridge::freeTransientResources() | |
142 { | |
143 freeReleasedMailbox(); | |
144 flush(); | |
145 freeMemoryIfPossible(MaxSize); | |
146 } | |
147 | |
148 bool Canvas2DLayerBridge::hasTransientResources() const | |
149 { | |
150 return hasReleasedMailbox() || bytesAllocated(); | |
151 } | |
152 | |
132 void Canvas2DLayerBridge::limitPendingFrames() | 153 void Canvas2DLayerBridge::limitPendingFrames() |
133 { | 154 { |
134 ASSERT(!m_destructionInProgress); | 155 ASSERT(!m_destructionInProgress); |
135 if (m_didRecordDrawCommand) { | 156 if (m_didRecordDrawCommand) { |
136 m_framesPending++; | 157 m_framesPending++; |
137 m_didRecordDrawCommand = false; | 158 m_didRecordDrawCommand = false; |
138 if (m_framesPending > 1) { | 159 if (m_framesPending > 1) { |
139 // Turn on the rate limiter if this layer tends to accumulate a | 160 // Turn on the rate limiter if this layer tends to accumulate a |
140 // non-discardable multi-frame backlog of draw commands. | 161 // non-discardable multi-frame backlog of draw commands. |
141 setRateLimitingEnabled(true); | 162 setRateLimitingEnabled(true); |
142 } | 163 } |
143 if (m_rateLimitingEnabled) { | 164 if (m_rateLimitingEnabled) { |
144 flush(); | 165 flush(); |
145 } | 166 } |
146 } | 167 } |
168 if (m_releasedMailboxInfo && ++m_framesSinceMailboxRelease >= 2) { | |
169 freeReleasedMailbox(); | |
170 } | |
147 } | 171 } |
148 | 172 |
149 void Canvas2DLayerBridge::prepareForDraw() | 173 void Canvas2DLayerBridge::prepareForDraw() |
150 { | 174 { |
151 ASSERT(!m_destructionInProgress); | 175 ASSERT(!m_destructionInProgress); |
152 ASSERT(m_layer); | 176 ASSERT(m_layer); |
153 if (!isValid()) { | 177 if (!isValid()) { |
154 if (m_canvas) { | 178 if (m_canvas) { |
155 // drop pending commands because there is no surface to draw to | 179 // drop pending commands because there is no surface to draw to |
156 m_canvas->silentFlush(); | 180 m_canvas->silentFlush(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((intptr _t)bytesFreed)); | 231 Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, -((intptr _t)bytesFreed)); |
208 m_bytesAllocated -= bytesFreed; | 232 m_bytesAllocated -= bytesFreed; |
209 return bytesFreed; | 233 return bytesFreed; |
210 } | 234 } |
211 | 235 |
212 void Canvas2DLayerBridge::flush() | 236 void Canvas2DLayerBridge::flush() |
213 { | 237 { |
214 ASSERT(!m_destructionInProgress); | 238 ASSERT(!m_destructionInProgress); |
215 if (m_canvas->hasPendingCommands()) { | 239 if (m_canvas->hasPendingCommands()) { |
216 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); | 240 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush"); |
241 freeReleasedMailbox(); // To avoid unnecessary triple-buffering | |
217 m_canvas->flush(); | 242 m_canvas->flush(); |
218 } | 243 } |
219 } | 244 } |
220 | 245 |
246 void Canvas2DLayerBridge::freeReleasedMailbox() | |
247 { | |
248 if (m_releasedMailboxInfo) { | |
249 ASSERT(m_releasedMailboxInfo->m_status == MailboxReleased); | |
250 if (m_releasedMailboxInfo->m_mailbox.syncPoint) { | |
251 context()->waitSyncPoint(m_releasedMailboxInfo->m_mailbox.syncPoint) ; | |
252 m_releasedMailboxInfo->m_mailbox.syncPoint = 0; | |
253 } | |
254 // Invalidate texture state in case the compositor altered it since the copy-on-write. | |
255 m_releasedMailboxInfo->m_image->getTexture()->invalidateCachedState(); | |
256 m_releasedMailboxInfo->m_image.clear(); | |
257 m_releasedMailboxInfo->m_status = MailboxAvailable; | |
258 m_releasedMailboxInfo = 0; | |
259 } | |
260 } | |
261 | |
221 blink::WebGraphicsContext3D* Canvas2DLayerBridge::context() | 262 blink::WebGraphicsContext3D* Canvas2DLayerBridge::context() |
222 { | 263 { |
223 // Check on m_layer is necessary because context() may be called during | 264 // Check on m_layer is necessary because context() may be called during |
224 // the destruction of m_layer | 265 // the destruction of m_layer |
225 if (m_layer) { | 266 if (m_layer) { |
226 isValid(); // To ensure rate limiter is disabled if context is lost. | 267 isValid(); // To ensure rate limiter is disabled if context is lost. |
227 } | 268 } |
228 return m_context->webContext(); | 269 return m_context->webContext(); |
229 } | 270 } |
230 | 271 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 m_canvas->silentFlush(); | 311 m_canvas->silentFlush(); |
271 return false; | 312 return false; |
272 } | 313 } |
273 if (!isValid()) | 314 if (!isValid()) |
274 return false; | 315 return false; |
275 // Release to skia textures that were previouosly released by the | 316 // Release to skia textures that were previouosly released by the |
276 // compositor. We do this before acquiring the next snapshot in | 317 // compositor. We do this before acquiring the next snapshot in |
277 // order to cap maximum gpu memory consumption. | 318 // order to cap maximum gpu memory consumption. |
278 m_context->makeContextCurrent(); | 319 m_context->makeContextCurrent(); |
279 flush(); | 320 flush(); |
280 Vector<MailboxInfo>::iterator mailboxInfo; | 321 |
281 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | 322 RefPtr<SkImage> image = adoptRef(m_canvas->newImageSnapshot()); |
282 if (mailboxInfo->m_status == MailboxReleased) { | 323 |
283 if (mailboxInfo->m_mailbox.syncPoint) { | |
284 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); | |
285 mailboxInfo->m_mailbox.syncPoint = 0; | |
286 } | |
287 // Invalidate texture state in case the compositor altered it since the copy-on-write. | |
288 mailboxInfo->m_image->getTexture()->invalidateCachedState(); | |
289 mailboxInfo->m_image.reset(0); | |
290 mailboxInfo->m_status = MailboxAvailable; | |
291 } | |
292 } | |
293 SkAutoTUnref<SkImage> image(m_canvas->newImageSnapshot()); | |
294 // Early exit if canvas was not drawn to since last prepareMailbox | 324 // Early exit if canvas was not drawn to since last prepareMailbox |
295 if (image->uniqueID() == m_lastImageId) | 325 if (image->uniqueID() == m_lastImageId) |
296 return false; | 326 return false; |
297 m_lastImageId = image->uniqueID(); | 327 m_lastImageId = image->uniqueID(); |
298 | 328 |
299 mailboxInfo = createMailboxInfo(); | 329 MailboxInfo* mailboxInfo = createMailboxInfo(); |
300 mailboxInfo->m_status = MailboxInUse; | 330 mailboxInfo->m_status = MailboxInUse; |
301 mailboxInfo->m_image.swap(&image); | 331 mailboxInfo->m_image = image; |
332 | |
302 // Because of texture sharing with the compositor, we must invalidate | 333 // Because of texture sharing with the compositor, we must invalidate |
303 // 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 |
304 // in SkSurface_Gpu does not make any false assumptions. | 335 // in SkSurface_Gpu does not make any false assumptions. |
305 mailboxInfo->m_image->getTexture()->invalidateCachedState(); | 336 mailboxInfo->m_image->getTexture()->invalidateCachedState(); |
306 | 337 |
307 ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); | 338 ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); |
308 ASSERT(mailboxInfo->m_image.get()); | 339 ASSERT(mailboxInfo->m_image.get()); |
309 ASSERT(mailboxInfo->m_image->getTexture()); | 340 ASSERT(mailboxInfo->m_image->getTexture()); |
310 | 341 |
311 m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->m_image->getTexture()->ge tTextureHandle()); | 342 m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->m_image->getTexture()->ge tTextureHandle()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 // kMaxSwapBuffersPending+1 (in render_widget.h). | 379 // kMaxSwapBuffersPending+1 (in render_widget.h). |
349 // Because of crbug.com/247874, it needs to be kMaxSwapBuffersPending+2. | 380 // Because of crbug.com/247874, it needs to be kMaxSwapBuffersPending+2. |
350 // TODO(piman): fix this. | 381 // TODO(piman): fix this. |
351 ASSERT(m_mailboxes.size() <= 4); | 382 ASSERT(m_mailboxes.size() <= 4); |
352 ASSERT(mailboxInfo < m_mailboxes.end()); | 383 ASSERT(mailboxInfo < m_mailboxes.end()); |
353 return mailboxInfo; | 384 return mailboxInfo; |
354 } | 385 } |
355 | 386 |
356 void Canvas2DLayerBridge::mailboxReleased(const blink::WebExternalTextureMailbox & mailbox) | 387 void Canvas2DLayerBridge::mailboxReleased(const blink::WebExternalTextureMailbox & mailbox) |
357 { | 388 { |
389 freeReleasedMailbox(); // Never have more than one mailbox in the released s tate. | |
358 Vector<MailboxInfo>::iterator mailboxInfo; | 390 Vector<MailboxInfo>::iterator mailboxInfo; |
359 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { | 391 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) { |
360 if (!memcmp(mailboxInfo->m_mailbox.name, mailbox.name, sizeof(mailbox.na me))) { | 392 if (!memcmp(mailboxInfo->m_mailbox.name, mailbox.name, sizeof(mailbox.na me))) { |
361 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint; | 393 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint; |
362 ASSERT(mailboxInfo->m_status == MailboxInUse); | 394 ASSERT(mailboxInfo->m_status == MailboxInUse); |
363 mailboxInfo->m_status = MailboxReleased; | 395 mailboxInfo->m_status = MailboxReleased; |
364 // Trigger Canvas2DLayerBridge self-destruction if this is the | 396 // Trigger Canvas2DLayerBridge self-destruction if this is the |
365 // last live mailbox and the layer bridge is not externally | 397 // last live mailbox and the layer bridge is not externally |
366 // referenced. | 398 // referenced. |
367 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this); | 399 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this); |
368 mailboxInfo->m_parentLayerBridge.clear(); | 400 mailboxInfo->m_parentLayerBridge.clear(); |
401 m_releasedMailboxInfo = mailboxInfo; | |
402 m_framesSinceMailboxRelease = 0; | |
403 if (hidden()) { | |
404 freeReleasedMailbox(); | |
405 } else { | |
406 Canvas2DLayerManager::get().setLayerHasFreeableResources(this); | |
407 } | |
369 return; | 408 return; |
370 } | 409 } |
371 } | 410 } |
372 } | 411 } |
373 | 412 |
374 blink::WebLayer* Canvas2DLayerBridge::layer() const | 413 blink::WebLayer* Canvas2DLayerBridge::layer() const |
375 { | 414 { |
376 ASSERT(m_layer); | 415 ASSERT(m_layer); |
377 return m_layer->layer(); | 416 return m_layer->layer(); |
378 } | 417 } |
(...skipping 15 matching lines...) Expand all Loading... | |
394 m_context->flush(); | 433 m_context->flush(); |
395 GrRenderTarget* renderTarget = m_canvas->getTopDevice()->accessRenderTarget( ); | 434 GrRenderTarget* renderTarget = m_canvas->getTopDevice()->accessRenderTarget( ); |
396 if (renderTarget) { | 435 if (renderTarget) { |
397 return renderTarget->asTexture()->getTextureHandle(); | 436 return renderTarget->asTexture()->getTextureHandle(); |
398 } | 437 } |
399 return 0; | 438 return 0; |
400 } | 439 } |
401 | 440 |
402 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { | 441 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) { |
403 // This copy constructor should only be used for Vector reallocation | 442 // This copy constructor should only be used for Vector reallocation |
404 // Assuming 'other' is to be destroyed, we swap m_image ownership | 443 // Assuming 'other' is to be destroyed, we transfer m_image ownership |
405 // rather than do a refcount dance. | 444 // rather than do a refcount dance. |
406 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); | 445 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox)); |
407 m_image.swap(const_cast<SkAutoTUnref<SkImage>*>(&other.m_image)); | 446 m_image = const_cast<MailboxInfo*>(&other)->m_image.release(); |
408 m_status = other.m_status; | 447 m_status = other.m_status; |
409 } | 448 } |
410 | 449 |
411 } | 450 } |
OLD | NEW |