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

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp

Issue 2738573002: Streamline the presentation of ImageBitmapRenderingContext (Closed)
Patch Set: Fixed expectations Created 3 years, 8 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) 2004, 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 277
278 if (m_context->is3d()) { 278 if (m_context->is3d()) {
279 updateExternallyAllocatedMemory(); 279 updateExternallyAllocatedMemory();
280 } 280 }
281 281
282 LayoutObject* layoutObject = this->layoutObject(); 282 LayoutObject* layoutObject = this->layoutObject();
283 if (layoutObject && m_context->is2d() && 283 if (layoutObject && m_context->is2d() &&
284 !m_context->creationAttributes().alpha()) { 284 !m_context->creationAttributes().alpha()) {
285 // In the alpha false case, canvas is initially opaque even though there is 285 // In the alpha false case, canvas is initially opaque even though there is
286 // no ImageBuffer, so we need to trigger an invalidation. 286 // no ImageBuffer, so we need to trigger an invalidation.
287 didDraw(FloatRect(0, 0, size().width(), size().height())); 287 didDraw();
288 } 288 }
289 289
290 setNeedsCompositingUpdate(); 290 setNeedsCompositingUpdate();
291 291
292 return m_context.get(); 292 return m_context.get();
293 } 293 }
294 294
295 bool HTMLCanvasElement::shouldBeDirectComposited() const { 295 bool HTMLCanvasElement::shouldBeDirectComposited() const {
296 return (m_context && m_context->isAccelerated()) || 296 return (m_context && m_context->isComposited()) ||
297 (hasImageBuffer() && buffer()->isExpensiveToPaint()) || 297 (hasImageBuffer() && buffer()->isExpensiveToPaint()) ||
298 (!!m_surfaceLayerBridge); 298 (!!m_surfaceLayerBridge);
299 } 299 }
300 300
301 bool HTMLCanvasElement::isPaintable() const { 301 bool HTMLCanvasElement::isPaintable() const {
302 return (m_context && m_context->isPaintable()) || 302 return (m_context && m_context->isPaintable()) ||
303 ImageBuffer::canCreateImageBuffer(size()); 303 ImageBuffer::canCreateImageBuffer(size());
304 } 304 }
305 305
306 bool HTMLCanvasElement::isAccelerated() const { 306 bool HTMLCanvasElement::isAccelerated() const {
(...skipping 12 matching lines...) Expand all
319 FloatRect inflatedRect = rect; 319 FloatRect inflatedRect = rect;
320 inflatedRect.inflate(1); 320 inflatedRect.inflate(1);
321 m_dirtyRect.unite(inflatedRect); 321 m_dirtyRect.unite(inflatedRect);
322 } else { 322 } else {
323 m_dirtyRect.unite(rect); 323 m_dirtyRect.unite(rect);
324 } 324 }
325 if (m_context && m_context->is2d() && hasImageBuffer()) 325 if (m_context && m_context->is2d() && hasImageBuffer())
326 buffer()->didDraw(rect); 326 buffer()->didDraw(rect);
327 } 327 }
328 328
329 void HTMLCanvasElement::didDraw() {
330 didDraw(FloatRect(0, 0, size().width(), size().height()));
331 }
332
329 void HTMLCanvasElement::finalizeFrame() { 333 void HTMLCanvasElement::finalizeFrame() {
330 if (hasImageBuffer()) 334 if (hasImageBuffer())
331 m_imageBuffer->finalizeFrame(); 335 m_imageBuffer->finalizeFrame();
332 336
333 // If the canvas is visible, notifying listeners is taken 337 // If the canvas is visible, notifying listeners is taken
334 // care of in the in doDeferredPaintInvalidation, which allows 338 // care of in the in doDeferredPaintInvalidation, which allows
335 // the frame to be grabbed prior to compositing, which is 339 // the frame to be grabbed prior to compositing, which is
336 // critically important because compositing may clear the canvas's 340 // critically important because compositing may clear the canvas's
337 // image. (e.g. WebGL context with preserveDrawingBuffer=false). 341 // image. (e.g. WebGL context with preserveDrawingBuffer=false).
338 // If the canvas is not visible, doDeferredPaintInvalidation 342 // If the canvas is not visible, doDeferredPaintInvalidation
339 // will not get called, so we need to take care of business here. 343 // will not get called, so we need to take care of business here.
340 if (!m_didNotifyListenersForCurrentFrame) 344 if (!m_didNotifyListenersForCurrentFrame)
341 notifyListenersCanvasChanged(); 345 notifyListenersCanvasChanged();
342 m_didNotifyListenersForCurrentFrame = false; 346 m_didNotifyListenersForCurrentFrame = false;
343 } 347 }
344 348
345 void HTMLCanvasElement::didDisableAcceleration() { 349 void HTMLCanvasElement::didDisableAcceleration() {
346 // We must force a paint invalidation on the canvas even if it's 350 // We must force a paint invalidation on the canvas even if it's
347 // content did not change because it layer was destroyed. 351 // content did not change because it layer was destroyed.
348 didDraw(FloatRect(0, 0, size().width(), size().height())); 352 didDraw();
349 } 353 }
350 354
351 void HTMLCanvasElement::restoreCanvasMatrixClipStack( 355 void HTMLCanvasElement::restoreCanvasMatrixClipStack(
352 PaintCanvas* canvas) const { 356 PaintCanvas* canvas) const {
353 if (m_context) 357 if (m_context)
354 m_context->restoreCanvasMatrixClipStack(canvas); 358 m_context->restoreCanvasMatrixClipStack(canvas);
355 } 359 }
356 360
357 void HTMLCanvasElement::doDeferredPaintInvalidation() { 361 void HTMLCanvasElement::doDeferredPaintInvalidation() {
358 DCHECK(!m_dirtyRect.isEmpty()); 362 DCHECK(!m_dirtyRect.isEmpty());
359 if (m_context->is2d()) { 363 if (m_context->is2d()) {
360 FloatRect srcRect(0, 0, size().width(), size().height()); 364 FloatRect srcRect(0, 0, size().width(), size().height());
361 m_dirtyRect.intersect(srcRect); 365 m_dirtyRect.intersect(srcRect);
362 LayoutBox* lb = layoutBox(); 366 LayoutBox* lb = layoutBox();
363 FloatRect invalidationRect; 367 FloatRect invalidationRect;
364 if (lb) { 368 if (lb) {
365 FloatRect mappedDirtyRect = 369 FloatRect mappedDirtyRect =
366 mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect())); 370 mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect()));
367 if (m_context->isAccelerated()) { 371 if (m_context->isComposited()) {
368 // Accelerated 2D canvases need the dirty rect to be expressed relative 372 // Accelerated 2D canvases need the dirty rect to be expressed relative
369 // to the content box, as opposed to the layout box. 373 // to the content box, as opposed to the layout box.
370 mappedDirtyRect.move(-lb->contentBoxOffset()); 374 mappedDirtyRect.move(-lb->contentBoxOffset());
371 } 375 }
372 invalidationRect = mappedDirtyRect; 376 invalidationRect = mappedDirtyRect;
373 } else { 377 } else {
374 invalidationRect = m_dirtyRect; 378 invalidationRect = m_dirtyRect;
375 } 379 }
380
381 if (m_dirtyRect.isEmpty())
382 return;
383
376 if (hasImageBuffer()) { 384 if (hasImageBuffer()) {
377 m_imageBuffer->doPaintInvalidation(invalidationRect); 385 m_imageBuffer->doPaintInvalidation(invalidationRect);
378 } 386 }
379 } 387 }
380 388
381 if (m_dirtyRect.isEmpty()) 389 if (m_context->getContextType() ==
382 return; 390 CanvasRenderingContext::ContextImageBitmap &&
391 m_context->platformLayer()) {
392 m_context->platformLayer()->invalidate();
393 }
383 394
384 notifyListenersCanvasChanged(); 395 notifyListenersCanvasChanged();
385 m_didNotifyListenersForCurrentFrame = true; 396 m_didNotifyListenersForCurrentFrame = true;
386 397
387 // Propagate the m_dirtyRect accumulated so far to the compositor 398 // Propagate the m_dirtyRect accumulated so far to the compositor
388 // before restarting with a blank dirty rect. 399 // before restarting with a blank dirty rect.
389 FloatRect srcRect(0, 0, size().width(), size().height()); 400 FloatRect srcRect(0, 0, size().width(), size().height());
390 401
391 LayoutBox* ro = layoutBox(); 402 LayoutBox* ro = layoutBox();
392 // Canvas content updates do not need to be propagated as 403 // Canvas content updates do not need to be propagated as
393 // paint invalidations if the canvas is accelerated, since 404 // paint invalidations if the canvas is composited separately, since
394 // the canvas contents are sent separately through a texture layer. 405 // the canvas contents are sent separately through a texture layer.
395 if (ro && (!m_context || !m_context->isAccelerated())) { 406 if (ro && (!m_context || !m_context->isComposited())) {
396 // If ro->contentBoxRect() is larger than srcRect the canvas's image is 407 // If ro->contentBoxRect() is larger than srcRect the canvas's image is
397 // being stretched, so we need to account for color bleeding caused by the 408 // being stretched, so we need to account for color bleeding caused by the
398 // interpollation filter. 409 // interpollation filter.
399 if (ro->contentBoxRect().width() > srcRect.width() || 410 if (ro->contentBoxRect().width() > srcRect.width() ||
400 ro->contentBoxRect().height() > srcRect.height()) { 411 ro->contentBoxRect().height() > srcRect.height()) {
401 m_dirtyRect.inflate(0.5); 412 m_dirtyRect.inflate(0.5);
402 } 413 }
403 414
404 m_dirtyRect.intersect(srcRect); 415 m_dirtyRect.intersect(srcRect);
405 LayoutRect mappedDirtyRect(enclosingIntRect( 416 LayoutRect mappedDirtyRect(enclosingIntRect(
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if (hadImageBuffer) 504 if (hadImageBuffer)
494 layoutObject->setShouldDoFullPaintInvalidation(); 505 layoutObject->setShouldDoFullPaintInvalidation();
495 } 506 }
496 } 507 }
497 } 508 }
498 509
499 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const { 510 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const {
500 if (placeholderFrame()) 511 if (placeholderFrame())
501 return false; 512 return false;
502 DCHECK(m_context); 513 DCHECK(m_context);
503 if (!m_context->isAccelerated()) 514 if (!m_context->isComposited())
504 return true; 515 return true;
505 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) 516 if (layoutBox() && layoutBox()->hasAcceleratedCompositing())
506 return false; 517 return false;
507 518
508 return true; 519 return true;
509 } 520 }
510 521
511 void HTMLCanvasElement::notifyListenersCanvasChanged() { 522 void HTMLCanvasElement::notifyListenersCanvasChanged() {
512 if (m_listeners.size() == 0) 523 if (m_listeners.size() == 0)
513 return; 524 return;
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 renderingContext()->paintRenderingResultsToCanvas(BackBuffer); 1292 renderingContext()->paintRenderingResultsToCanvas(BackBuffer);
1282 if (hasImageBuffer()) { 1293 if (hasImageBuffer()) {
1283 skImage = buffer()->newSkImageSnapshot(hint, reason); 1294 skImage = buffer()->newSkImageSnapshot(hint, reason);
1284 } else { 1295 } else {
1285 skImage = createTransparentSkImage(size()); 1296 skImage = createTransparentSkImage(size());
1286 } 1297 }
1287 } else { 1298 } else {
1288 if (ExpensiveCanvasHeuristicParameters:: 1299 if (ExpensiveCanvasHeuristicParameters::
1289 DisableAccelerationToAvoidReadbacks && 1300 DisableAccelerationToAvoidReadbacks &&
1290 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() && 1301 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() &&
1291 hint == PreferNoAcceleration && m_context->isAccelerated() && 1302 hint == PreferNoAcceleration && hasImageBuffer() &&
1292 hasImageBuffer()) { 1303 buffer()->isAccelerated()) {
1293 buffer()->disableAcceleration(); 1304 buffer()->disableAcceleration();
1294 } 1305 }
1295 RefPtr<Image> image = renderingContext()->getImage(hint, reason); 1306 RefPtr<Image> image = renderingContext()->getImage(hint, reason);
1296 if (image) { 1307 if (image) {
1297 skImage = image->imageForCurrentFrame(); 1308 skImage = image->imageForCurrentFrame();
1298 } else { 1309 } else {
1299 skImage = createTransparentSkImage(size()); 1310 skImage = createTransparentSkImage(size());
1300 } 1311 }
1301 } 1312 }
1302 1313
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 // Creates a placeholder layer first before Surface is created. 1473 // Creates a placeholder layer first before Surface is created.
1463 m_surfaceLayerBridge->createSolidColorLayer(); 1474 m_surfaceLayerBridge->createSolidColorLayer();
1464 } 1475 }
1465 } 1476 }
1466 1477
1467 void HTMLCanvasElement::OnWebLayerReplaced() { 1478 void HTMLCanvasElement::OnWebLayerReplaced() {
1468 setNeedsCompositingUpdate(); 1479 setNeedsCompositingUpdate();
1469 } 1480 }
1470 1481
1471 } // namespace blink 1482 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698