Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: sky/engine/platform/graphics/Canvas2DLayerBridge.cpp

Issue 1229113003: Remove some unneeded DEPS from //sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26
27 #include "sky/engine/platform/graphics/Canvas2DLayerBridge.h"
28
29 #include "sky/engine/platform/TraceEvent.h"
30 #include "sky/engine/platform/graphics/Canvas2DLayerManager.h"
31 #include "sky/engine/platform/graphics/ImageBuffer.h"
32 #include "sky/engine/public/platform/Platform.h"
33 #include "sky/engine/public/platform/WebGraphicsContext3D.h"
34 #include "sky/engine/public/platform/WebGraphicsContext3DProvider.h"
35 #include "sky/engine/wtf/RefCountedLeakCounter.h"
36 #include "third_party/skia/include/core/SkDevice.h"
37 #include "third_party/skia/include/core/SkSurface.h"
38 #include "third_party/skia/include/gpu/GrContext.h"
39
40 namespace {
41 enum {
42 InvalidMailboxIndex = -1,
43 };
44
45 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, canvas2DLayerBridgeInstance Counter, ("Canvas2DLayerBridge"));
46 }
47
48 namespace blink {
49
50 static PassRefPtr<SkSurface> createSkSurface(GrContext* gr, const IntSize& size, int msaaSampleCount = 0)
51 {
52 if (!gr)
53 return nullptr;
54 gr->resetContext();
55 SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
56 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
57 return adoptRef(SkSurface::NewRenderTarget(gr, SkSurface::kNo_Budgeted, info , msaaSampleCount, &disableLCDProps));
58 }
59
60 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size, OpacityMode opacityMode, int msaaSampleCount)
61 {
62 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_NAME_PROCESS);
63 OwnPtr<WebGraphicsContext3DProvider> contextProvider = adoptPtr(Platform::cu rrent()->createSharedOffscreenGraphicsContext3DProvider());
64 if (!contextProvider)
65 return nullptr;
66 RefPtr<SkSurface> surface(createSkSurface(contextProvider->grContext(), size , msaaSampleCount));
67 if (!surface)
68 return nullptr;
69 RefPtr<Canvas2DLayerBridge> layerBridge;
70 OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface. get()));
71 layerBridge = adoptRef(new Canvas2DLayerBridge(contextProvider.release(), ca nvas.release(), surface.release(), msaaSampleCount, opacityMode));
72 return layerBridge.release();
73 }
74
75 Canvas2DLayerBridge::Canvas2DLayerBridge(PassOwnPtr<WebGraphicsContext3DProvider > contextProvider, PassOwnPtr<SkDeferredCanvas> canvas, PassRefPtr<SkSurface> su rface, int msaaSampleCount, OpacityMode opacityMode)
76 : m_canvas(canvas)
77 , m_surface(surface)
78 , m_contextProvider(contextProvider)
79 , m_imageBuffer(0)
80 , m_msaaSampleCount(msaaSampleCount)
81 , m_bytesAllocated(0)
82 , m_didRecordDrawCommand(false)
83 , m_isSurfaceValid(true)
84 , m_framesPending(0)
85 , m_framesSinceMailboxRelease(0)
86 , m_destructionInProgress(false)
87 , m_rateLimitingEnabled(false)
88 , m_isHidden(false)
89 , m_next(0)
90 , m_prev(0)
91 , m_lastImageId(0)
92 , m_releasedMailboxInfoIndex(InvalidMailboxIndex)
93 {
94 ASSERT(m_canvas);
95 ASSERT(m_surface);
96 ASSERT(m_contextProvider);
97 // Used by browser tests to detect the use of a Canvas2DLayerBridge.
98 TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_ SCOPE_NAME_PROCESS);
99 m_layer = nullptr;
100 CRASH(); // No compositor.
101 m_layer->setOpaque(opacityMode == Opaque);
102 m_layer->setBlendBackgroundColor(opacityMode != Opaque);
103 m_layer->setRateLimitContext(m_rateLimitingEnabled);
104 m_canvas->setNotificationClient(this);
105 #ifndef NDEBUG
106 canvas2DLayerBridgeInstanceCounter.increment();
107 #endif
108 }
109
110 Canvas2DLayerBridge::~Canvas2DLayerBridge()
111 {
112 ASSERT(m_destructionInProgress);
113 ASSERT(!Canvas2DLayerManager::get().isInList(this));
114 m_layer.clear();
115 freeReleasedMailbox();
116 #if ENABLE(ASSERT)
117 Vector<MailboxInfo>::iterator mailboxInfo;
118 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); ++m ailboxInfo) {
119 ASSERT(mailboxInfo->m_status != MailboxInUse);
120 ASSERT(mailboxInfo->m_status != MailboxReleased || m_contextProvider->co ntext3d()->isContextLost() || !m_isSurfaceValid);
121 }
122 #endif
123 m_mailboxes.clear();
124 #ifndef NDEBUG
125 canvas2DLayerBridgeInstanceCounter.decrement();
126 #endif
127 }
128
129 void Canvas2DLayerBridge::beginDestruction()
130 {
131 ASSERT(!m_destructionInProgress);
132 setRateLimitingEnabled(false);
133 m_canvas->silentFlush();
134 m_imageBuffer = 0;
135 freeTransientResources();
136 setIsHidden(true);
137 m_destructionInProgress = true;
138 m_canvas->setNotificationClient(0);
139 m_surface.clear();
140 m_canvas.clear();
141 m_layer->clearTexture();
142 // Orphaning the layer is required to trigger the recration of a new layer
143 // in the case where destruction is caused by a canvas resize. Test:
144 // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html
145 m_layer->layer()->removeFromParent();
146 // To anyone who ever hits this assert: Please update crbug.com/344666
147 // with repro steps.
148 ASSERT(!m_bytesAllocated);
149 }
150
151 void Canvas2DLayerBridge::setIsHidden(bool hidden)
152 {
153 ASSERT(!m_destructionInProgress);
154 bool newHiddenValue = hidden || m_destructionInProgress;
155 if (m_isHidden == newHiddenValue)
156 return;
157
158 m_isHidden = newHiddenValue;
159 if (isHidden()) {
160 freeTransientResources();
161 }
162 }
163
164 void Canvas2DLayerBridge::willAccessPixels()
165 {
166 // A readback operation may alter the texture parameters, which may affect
167 // the compositor's behavior. Therefore, we must trigger copy-on-write
168 // even though we are not technically writing to the texture, only to its
169 // parameters.
170 m_surface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
171 }
172
173 void Canvas2DLayerBridge::freeTransientResources()
174 {
175 ASSERT(!m_destructionInProgress);
176 if (!m_isSurfaceValid)
177 return;
178 freeReleasedMailbox();
179 flush();
180 freeMemoryIfPossible(bytesAllocated());
181 ASSERT(!hasTransientResources());
182 }
183
184 bool Canvas2DLayerBridge::hasTransientResources() const
185 {
186 return !m_destructionInProgress && (hasReleasedMailbox() || bytesAllocated() );
187 }
188
189 void Canvas2DLayerBridge::limitPendingFrames()
190 {
191 ASSERT(!m_destructionInProgress);
192 if (isHidden()) {
193 freeTransientResources();
194 return;
195 }
196 if (m_didRecordDrawCommand) {
197 m_framesPending++;
198 m_didRecordDrawCommand = false;
199 if (m_framesPending > 1) {
200 // Turn on the rate limiter if this layer tends to accumulate a
201 // non-discardable multi-frame backlog of draw commands.
202 setRateLimitingEnabled(true);
203 }
204 if (m_rateLimitingEnabled) {
205 flush();
206 }
207 }
208 ++m_framesSinceMailboxRelease;
209 if (releasedMailboxHasExpired()) {
210 freeReleasedMailbox();
211 }
212 }
213
214 void Canvas2DLayerBridge::prepareForDraw()
215 {
216 ASSERT(!m_destructionInProgress);
217 ASSERT(m_layer);
218 if (!checkSurfaceValid()) {
219 if (m_canvas) {
220 // drop pending commands because there is no surface to draw to
221 m_canvas->silentFlush();
222 }
223 return;
224 }
225 }
226
227 void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca ted)
228 {
229 ASSERT(!m_destructionInProgress);
230 intptr_t delta = (intptr_t)bytesAllocated - (intptr_t)m_bytesAllocated;
231 m_bytesAllocated = bytesAllocated;
232 Canvas2DLayerManager::get().layerTransientResourceAllocationChanged(this, de lta);
233 }
234
235 size_t Canvas2DLayerBridge::storageAllocatedForRecording()
236 {
237 return m_canvas->storageAllocatedForRecording();
238 }
239
240 void Canvas2DLayerBridge::flushedDrawCommands()
241 {
242 ASSERT(!m_destructionInProgress);
243 storageAllocatedForRecordingChanged(storageAllocatedForRecording());
244 m_framesPending = 0;
245 }
246
247 void Canvas2DLayerBridge::skippedPendingDrawCommands()
248 {
249 ASSERT(!m_destructionInProgress);
250 // Stop triggering the rate limiter if SkDeferredCanvas is detecting
251 // and optimizing overdraw.
252 setRateLimitingEnabled(false);
253 flushedDrawCommands();
254 }
255
256 void Canvas2DLayerBridge::setRateLimitingEnabled(bool enabled)
257 {
258 ASSERT(!m_destructionInProgress);
259 if (m_rateLimitingEnabled != enabled) {
260 m_rateLimitingEnabled = enabled;
261 m_layer->setRateLimitContext(m_rateLimitingEnabled);
262 }
263 }
264
265 size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree)
266 {
267 ASSERT(!m_destructionInProgress);
268 size_t bytesFreed = m_canvas->freeMemoryIfPossible(bytesToFree);
269 m_bytesAllocated -= bytesFreed;
270 if (bytesFreed)
271 Canvas2DLayerManager::get().layerTransientResourceAllocationChanged(this , -((intptr_t)bytesFreed));
272 return bytesFreed;
273 }
274
275 void Canvas2DLayerBridge::flush()
276 {
277 ASSERT(!m_destructionInProgress);
278 if (m_canvas->hasPendingCommands()) {
279 TRACE_EVENT0("cc", "Canvas2DLayerBridge::flush");
280 freeReleasedMailbox(); // To avoid unnecessary triple-buffering
281 m_canvas->flush();
282 }
283 }
284
285 bool Canvas2DLayerBridge::releasedMailboxHasExpired()
286 {
287 // This heuristic indicates that the canvas is not being
288 // actively presented by the compositor (3 frames rendered since
289 // last mailbox release), suggesting that double buffering is not required.
290 return hasReleasedMailbox() && m_framesSinceMailboxRelease > 2;
291 }
292
293 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::releasedMailboxInfo()
294 {
295 return hasReleasedMailbox() ? &m_mailboxes[m_releasedMailboxInfoIndex] : 0;
296 }
297
298 bool Canvas2DLayerBridge::hasReleasedMailbox() const
299 {
300 return m_releasedMailboxInfoIndex != InvalidMailboxIndex;
301 }
302
303 void Canvas2DLayerBridge::freeReleasedMailbox()
304 {
305 if (!m_isSurfaceValid || m_contextProvider->context3d()->isContextLost())
306 return;
307 MailboxInfo* mailboxInfo = releasedMailboxInfo();
308 if (!mailboxInfo)
309 return;
310
311 ASSERT(mailboxInfo->m_status == MailboxReleased);
312 if (mailboxInfo->m_mailbox.syncPoint) {
313 context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint);
314 mailboxInfo->m_mailbox.syncPoint = 0;
315 }
316 // Invalidate texture state in case the compositor altered it since the copy -on-write.
317 if (mailboxInfo->m_image) {
318 mailboxInfo->m_image->getTexture()->textureParamsModified();
319 mailboxInfo->m_image.clear();
320 }
321 mailboxInfo->m_status = MailboxAvailable;
322 m_releasedMailboxInfoIndex = InvalidMailboxIndex;
323 Canvas2DLayerManager::get().layerTransientResourceAllocationChanged(this);
324 }
325
326 WebGraphicsContext3D* Canvas2DLayerBridge::context()
327 {
328 // Check on m_layer is necessary because context() may be called during
329 // the destruction of m_layer
330 if (m_layer && !m_destructionInProgress)
331 checkSurfaceValid(); // To ensure rate limiter is disabled if context is lost.
332 return m_contextProvider ? m_contextProvider->context3d() : 0;
333 }
334
335 bool Canvas2DLayerBridge::checkSurfaceValid()
336 {
337 ASSERT(!m_destructionInProgress);
338 if (m_destructionInProgress || !m_isSurfaceValid)
339 return false;
340 if (m_contextProvider->context3d()->isContextLost()) {
341 m_isSurfaceValid = false;
342 m_surface.clear();
343 if (m_imageBuffer)
344 m_imageBuffer->notifySurfaceInvalid();
345 setRateLimitingEnabled(false);
346 }
347 return m_isSurfaceValid;
348 }
349
350 bool Canvas2DLayerBridge::restoreSurface()
351 {
352 ASSERT(!m_destructionInProgress);
353 if (m_destructionInProgress)
354 return false;
355 ASSERT(m_layer && !m_isSurfaceValid);
356
357 WebGraphicsContext3D* sharedContext = 0;
358 // We must clear the mailboxes before calling m_layer->clearTexture() to pre vent
359 // re-entry via mailboxReleased from operating on defunct GrContext objects.
360 m_mailboxes.clear();
361 m_releasedMailboxInfoIndex = InvalidMailboxIndex;
362 m_layer->clearTexture();
363 m_contextProvider = adoptPtr(Platform::current()->createSharedOffscreenGraph icsContext3DProvider());
364 if (m_contextProvider)
365 sharedContext = m_contextProvider->context3d();
366
367 if (sharedContext && !sharedContext->isContextLost()) {
368 IntSize size(m_canvas->getTopDevice()->width(), m_canvas->getTopDevice() ->height());
369 RefPtr<SkSurface> surface(createSkSurface(m_contextProvider->grContext() , size, m_msaaSampleCount));
370 if (surface.get()) {
371 m_surface = surface.release();
372 m_canvas->setSurface(m_surface.get());
373 m_isSurfaceValid = true;
374 // FIXME: draw sad canvas picture into new buffer crbug.com/243842
375 }
376 }
377
378 return m_isSurfaceValid;
379 }
380
381 bool Canvas2DLayerBridge::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExternalBitmap* bitmap)
382 {
383 if (m_destructionInProgress) {
384 // It can be hit in the following sequence.
385 // 1. Canvas draws something.
386 // 2. The compositor begins the frame.
387 // 3. Javascript makes a context be lost.
388 // 4. Here.
389 return false;
390 }
391 if (bitmap) {
392 // Using accelerated 2d canvas with software renderer, which
393 // should only happen in tests that use fake graphics contexts
394 // or in Android WebView in software mode. In this case, we do
395 // not care about producing any results for this canvas.
396 m_canvas->silentFlush();
397 m_lastImageId = 0;
398 return false;
399 }
400 if (!checkSurfaceValid())
401 return false;
402
403 WebGraphicsContext3D* webContext = context();
404
405 // Release to skia textures that were previouosly released by the
406 // compositor. We do this before acquiring the next snapshot in
407 // order to cap maximum gpu memory consumption.
408 flush();
409
410 RefPtr<SkImage> image = adoptRef(m_canvas->newImageSnapshot());
411
412 // Early exit if canvas was not drawn to since last prepareMailbox
413 if (image->uniqueID() == m_lastImageId)
414 return false;
415 m_lastImageId = image->uniqueID();
416
417 MailboxInfo* mailboxInfo = createMailboxInfo();
418 mailboxInfo->m_status = MailboxInUse;
419 mailboxInfo->m_image = image;
420
421 ASSERT(mailboxInfo->m_mailbox.syncPoint == 0);
422 ASSERT(mailboxInfo->m_image.get());
423 ASSERT(mailboxInfo->m_image->getTexture());
424
425 // Because of texture sharing with the compositor, we must invalidate
426 // the state cached in skia so that the deferred copy on write
427 // in SkSurface_Gpu does not make any false assumptions.
428 mailboxInfo->m_image->getTexture()->textureParamsModified();
429
430 webContext->bindTexture(GL_TEXTURE_2D, mailboxInfo->m_image->getTexture()->g etTextureHandle());
431 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
432 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
433 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
434 webContext->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
435 webContext->produceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo->m_mailbox.nam e);
436 if (isHidden()) {
437 // With hidden canvases, we release the SkImage immediately because
438 // there is no need for animations to be double buffered.
439 mailboxInfo->m_image.clear();
440 } else {
441 webContext->flush();
442 mailboxInfo->m_mailbox.syncPoint = webContext->insertSyncPoint();
443 }
444 webContext->bindTexture(GL_TEXTURE_2D, 0);
445 // Because we are changing the texture binding without going through skia,
446 // we must dirty the context.
447 m_contextProvider->grContext()->resetContext(kTextureBinding_GrGLBackendStat e);
448
449 // set m_parentLayerBridge to make sure 'this' stays alive as long as it has
450 // live mailboxes
451 ASSERT(!mailboxInfo->m_parentLayerBridge);
452 mailboxInfo->m_parentLayerBridge = this;
453 *outMailbox = mailboxInfo->m_mailbox;
454
455 return true;
456 }
457
458 Canvas2DLayerBridge::MailboxInfo* Canvas2DLayerBridge::createMailboxInfo() {
459 ASSERT(!m_destructionInProgress);
460 MailboxInfo* mailboxInfo;
461 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mai lboxInfo++) {
462 if (mailboxInfo->m_status == MailboxAvailable) {
463 return mailboxInfo;
464 }
465 }
466
467 // No available mailbox: create one.
468 m_mailboxes.grow(m_mailboxes.size() + 1);
469 mailboxInfo = &m_mailboxes.last();
470 context()->genMailboxCHROMIUM(mailboxInfo->m_mailbox.name);
471 // Worst case, canvas is triple buffered. More than 3 active mailboxes
472 // means there is a problem.
473 // For the single-threaded case, this value needs to be at least
474 // kMaxSwapBuffersPending+1 (in render_widget.h).
475 // Because of crbug.com/247874, it needs to be kMaxSwapBuffersPending+2.
476 // TODO(piman): fix this.
477 ASSERT(m_mailboxes.size() <= 4);
478 ASSERT(mailboxInfo < m_mailboxes.end());
479 return mailboxInfo;
480 }
481
482 void Canvas2DLayerBridge::mailboxReleased(const WebExternalTextureMailbox& mailb ox, bool lostResource)
483 {
484 freeReleasedMailbox(); // Never have more than one mailbox in the released s tate.
485 bool contextLost = !m_isSurfaceValid || m_contextProvider->context3d()->isCo ntextLost();
486 Vector<MailboxInfo>::iterator mailboxInfo;
487 for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); ++m ailboxInfo) {
488 if (nameEquals(mailboxInfo->m_mailbox, mailbox)) {
489 mailboxInfo->m_mailbox.syncPoint = mailbox.syncPoint;
490 ASSERT(mailboxInfo->m_status == MailboxInUse);
491 ASSERT(mailboxInfo->m_parentLayerBridge.get() == this);
492
493 if (contextLost) {
494 // No need to clean up the mailbox resource, but make sure the
495 // mailbox can also be reusable once the context is restored.
496 mailboxInfo->m_status = MailboxAvailable;
497 m_releasedMailboxInfoIndex = InvalidMailboxIndex;
498 Canvas2DLayerManager::get().layerTransientResourceAllocationChan ged(this);
499 } else if (lostResource) {
500 // In case of the resource is lost, we need to delete the backin g
501 // texture and remove the mailbox from list to avoid reusing it
502 // in future.
503 if (mailboxInfo->m_image) {
504 GrTexture* texture = mailboxInfo->m_image->getTexture();
505 if (texture)
506 texture->textureParamsModified();
507 mailboxInfo->m_image.clear();
508 }
509 size_t i = mailboxInfo - m_mailboxes.begin();
510 m_mailboxes.remove(i);
511 Canvas2DLayerManager::get().layerTransientResourceAllocationChan ged(this);
512 // Here we need to return early since mailboxInfo removal would
513 // also clear m_parentLayerBridge reference.
514 return;
515 } else {
516 mailboxInfo->m_status = MailboxReleased;
517 m_releasedMailboxInfoIndex = mailboxInfo - m_mailboxes.begin();
518 m_framesSinceMailboxRelease = 0;
519 if (isHidden()) {
520 freeReleasedMailbox();
521 } else {
522 ASSERT(!m_destructionInProgress);
523 Canvas2DLayerManager::get().layerTransientResourceAllocation Changed(this);
524 }
525 }
526 // Trigger Canvas2DLayerBridge self-destruction if this is the
527 // last live mailbox and the layer bridge is not externally
528 // referenced.
529 mailboxInfo->m_parentLayerBridge.clear();
530 return;
531 }
532 }
533 }
534
535 WebLayer* Canvas2DLayerBridge::layer() const
536 {
537 ASSERT(!m_destructionInProgress);
538 ASSERT(m_layer);
539 return m_layer->layer();
540 }
541
542 void Canvas2DLayerBridge::finalizeFrame()
543 {
544 ASSERT(!m_destructionInProgress);
545 Canvas2DLayerManager::get().layerDidDraw(this);
546 m_didRecordDrawCommand = true;
547 }
548
549 Platform3DObject Canvas2DLayerBridge::getBackingTexture()
550 {
551 ASSERT(!m_destructionInProgress);
552 if (!checkSurfaceValid())
553 return 0;
554 m_canvas->flush();
555 context()->flush();
556 GrRenderTarget* renderTarget = m_canvas->getTopDevice()->accessRenderTarget( );
557 if (renderTarget) {
558 return renderTarget->asTexture()->getTextureHandle();
559 }
560 return 0;
561 }
562
563 Canvas2DLayerBridge::MailboxInfo::MailboxInfo(const MailboxInfo& other) {
564 // This copy constructor should only be used for Vector reallocation
565 // Assuming 'other' is to be destroyed, we transfer m_image and
566 // m_parentLayerBridge ownership rather than do a refcount dance.
567 memcpy(&m_mailbox, &other.m_mailbox, sizeof(m_mailbox));
568 m_image = const_cast<MailboxInfo*>(&other)->m_image.release();
569 m_parentLayerBridge = const_cast<MailboxInfo*>(&other)->m_parentLayerBridge. release();
570 m_status = other.m_status;
571 }
572
573 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/platform/graphics/Canvas2DLayerBridge.h ('k') | sky/engine/platform/graphics/Canvas2DLayerManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698