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

Side by Side Diff: Source/core/platform/graphics/chromium/Canvas2DLayerBridge.cpp

Issue 21858004: Refactoring Canvas2DLayerBridge to make it easier to write unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed similarity blunder Created 7 years, 4 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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698