| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 notifyListenersCanvasChanged(); | 336 notifyListenersCanvasChanged(); |
| 333 } | 337 } |
| 334 | 338 |
| 335 void HTMLCanvasElement::didDisableAcceleration() { | 339 void HTMLCanvasElement::didDisableAcceleration() { |
| 336 // We must force a paint invalidation on the canvas even if it's | 340 // We must force a paint invalidation on the canvas even if it's |
| 337 // content did not change because it layer was destroyed. | 341 // content did not change because it layer was destroyed. |
| 338 didDraw(FloatRect(0, 0, size().width(), size().height())); | 342 didDraw(); |
| 339 } | 343 } |
| 340 | 344 |
| 341 void HTMLCanvasElement::restoreCanvasMatrixClipStack( | 345 void HTMLCanvasElement::restoreCanvasMatrixClipStack( |
| 342 PaintCanvas* canvas) const { | 346 PaintCanvas* canvas) const { |
| 343 if (m_context) | 347 if (m_context) |
| 344 m_context->restoreCanvasMatrixClipStack(canvas); | 348 m_context->restoreCanvasMatrixClipStack(canvas); |
| 345 } | 349 } |
| 346 | 350 |
| 347 void HTMLCanvasElement::doDeferredPaintInvalidation() { | 351 void HTMLCanvasElement::doDeferredPaintInvalidation() { |
| 348 DCHECK(!m_dirtyRect.isEmpty()); | 352 DCHECK(!m_dirtyRect.isEmpty()); |
| 349 if (m_context->is2d()) { | 353 if (m_context->is2d()) { |
| 350 FloatRect srcRect(0, 0, size().width(), size().height()); | 354 FloatRect srcRect(0, 0, size().width(), size().height()); |
| 351 m_dirtyRect.intersect(srcRect); | 355 m_dirtyRect.intersect(srcRect); |
| 352 LayoutBox* lb = layoutBox(); | 356 LayoutBox* lb = layoutBox(); |
| 353 FloatRect invalidationRect; | 357 FloatRect invalidationRect; |
| 354 if (lb) { | 358 if (lb) { |
| 355 FloatRect mappedDirtyRect = | 359 FloatRect mappedDirtyRect = |
| 356 mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect())); | 360 mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect())); |
| 357 if (m_context->isAccelerated()) { | 361 if (m_context->isComposited()) { |
| 358 // Accelerated 2D canvases need the dirty rect to be expressed relative | 362 // Accelerated 2D canvases need the dirty rect to be expressed relative |
| 359 // to the content box, as opposed to the layout box. | 363 // to the content box, as opposed to the layout box. |
| 360 mappedDirtyRect.move(-lb->contentBoxOffset()); | 364 mappedDirtyRect.move(-lb->contentBoxOffset()); |
| 361 } | 365 } |
| 362 invalidationRect = mappedDirtyRect; | 366 invalidationRect = mappedDirtyRect; |
| 363 } else { | 367 } else { |
| 364 invalidationRect = m_dirtyRect; | 368 invalidationRect = m_dirtyRect; |
| 365 } | 369 } |
| 366 if (hasImageBuffer()) { | 370 if (hasImageBuffer()) { |
| 367 m_imageBuffer->doPaintInvalidation(invalidationRect); | 371 m_imageBuffer->doPaintInvalidation(invalidationRect); |
| 368 } | 372 } |
| 369 } | 373 } |
| 370 | 374 |
| 371 if (m_dirtyRect.isEmpty()) | 375 if (m_dirtyRect.isEmpty()) |
| 372 return; | 376 return; |
| 373 | 377 |
| 374 // Propagate the m_dirtyRect accumulated so far to the compositor | 378 // Propagate the m_dirtyRect accumulated so far to the compositor |
| 375 // before restarting with a blank dirty rect. | 379 // before restarting with a blank dirty rect. |
| 376 FloatRect srcRect(0, 0, size().width(), size().height()); | 380 FloatRect srcRect(0, 0, size().width(), size().height()); |
| 377 | 381 |
| 378 LayoutBox* ro = layoutBox(); | 382 LayoutBox* ro = layoutBox(); |
| 379 // Canvas content updates do not need to be propagated as | 383 // Canvas content updates do not need to be propagated as |
| 380 // paint invalidations if the canvas is accelerated, since | 384 // paint invalidations if the canvas is composited separately, since |
| 381 // the canvas contents are sent separately through a texture layer. | 385 // the canvas contents are sent separately through a texture layer. |
| 382 if (ro && (!m_context || !m_context->isAccelerated())) { | 386 if (ro && (!m_context || !m_context->isComposited())) { |
| 383 // If ro->contentBoxRect() is larger than srcRect the canvas's image is | 387 // If ro->contentBoxRect() is larger than srcRect the canvas's image is |
| 384 // being stretched, so we need to account for color bleeding caused by the | 388 // being stretched, so we need to account for color bleeding caused by the |
| 385 // interpollation filter. | 389 // interpollation filter. |
| 386 if (ro->contentBoxRect().width() > srcRect.width() || | 390 if (ro->contentBoxRect().width() > srcRect.width() || |
| 387 ro->contentBoxRect().height() > srcRect.height()) { | 391 ro->contentBoxRect().height() > srcRect.height()) { |
| 388 m_dirtyRect.inflate(0.5); | 392 m_dirtyRect.inflate(0.5); |
| 389 } | 393 } |
| 390 | 394 |
| 391 m_dirtyRect.intersect(srcRect); | 395 m_dirtyRect.intersect(srcRect); |
| 392 LayoutRect mappedDirtyRect(enclosingIntRect( | 396 LayoutRect mappedDirtyRect(enclosingIntRect( |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 if (hadImageBuffer) | 484 if (hadImageBuffer) |
| 481 layoutObject->setShouldDoFullPaintInvalidation(); | 485 layoutObject->setShouldDoFullPaintInvalidation(); |
| 482 } | 486 } |
| 483 } | 487 } |
| 484 } | 488 } |
| 485 | 489 |
| 486 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const { | 490 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const { |
| 487 if (placeholderFrame()) | 491 if (placeholderFrame()) |
| 488 return false; | 492 return false; |
| 489 DCHECK(m_context); | 493 DCHECK(m_context); |
| 490 if (!m_context->isAccelerated()) | 494 if (!m_context->isComposited()) |
| 491 return true; | 495 return true; |
| 492 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) | 496 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) |
| 493 return false; | 497 return false; |
| 494 | 498 |
| 495 return true; | 499 return true; |
| 496 } | 500 } |
| 497 | 501 |
| 498 void HTMLCanvasElement::notifyListenersCanvasChanged() { | 502 void HTMLCanvasElement::notifyListenersCanvasChanged() { |
| 499 if (m_listeners.size() == 0) | 503 if (m_listeners.size() == 0) |
| 500 return; | 504 return; |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 renderingContext()->paintRenderingResultsToCanvas(BackBuffer); | 1272 renderingContext()->paintRenderingResultsToCanvas(BackBuffer); |
| 1269 if (hasImageBuffer()) { | 1273 if (hasImageBuffer()) { |
| 1270 skImage = buffer()->newSkImageSnapshot(hint, reason); | 1274 skImage = buffer()->newSkImageSnapshot(hint, reason); |
| 1271 } else { | 1275 } else { |
| 1272 skImage = createTransparentSkImage(size()); | 1276 skImage = createTransparentSkImage(size()); |
| 1273 } | 1277 } |
| 1274 } else { | 1278 } else { |
| 1275 if (ExpensiveCanvasHeuristicParameters:: | 1279 if (ExpensiveCanvasHeuristicParameters:: |
| 1276 DisableAccelerationToAvoidReadbacks && | 1280 DisableAccelerationToAvoidReadbacks && |
| 1277 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() && | 1281 !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() && |
| 1278 hint == PreferNoAcceleration && m_context->isAccelerated() && | 1282 hint == PreferNoAcceleration && hasImageBuffer() && |
| 1279 hasImageBuffer()) { | 1283 buffer()->isAccelerated()) { |
| 1280 buffer()->disableAcceleration(); | 1284 buffer()->disableAcceleration(); |
| 1281 } | 1285 } |
| 1282 RefPtr<Image> image = renderingContext()->getImage(hint, reason); | 1286 RefPtr<Image> image = renderingContext()->getImage(hint, reason); |
| 1283 if (image) { | 1287 if (image) { |
| 1284 skImage = image->imageForCurrentFrame(); | 1288 skImage = image->imageForCurrentFrame(); |
| 1285 } else { | 1289 } else { |
| 1286 skImage = createTransparentSkImage(size()); | 1290 skImage = createTransparentSkImage(size()); |
| 1287 } | 1291 } |
| 1288 } | 1292 } |
| 1289 | 1293 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 // Creates a placeholder layer first before Surface is created. | 1453 // Creates a placeholder layer first before Surface is created. |
| 1450 m_surfaceLayerBridge->createSolidColorLayer(); | 1454 m_surfaceLayerBridge->createSolidColorLayer(); |
| 1451 } | 1455 } |
| 1452 } | 1456 } |
| 1453 | 1457 |
| 1454 void HTMLCanvasElement::OnWebLayerReplaced() { | 1458 void HTMLCanvasElement::OnWebLayerReplaced() { |
| 1455 setNeedsCompositingUpdate(); | 1459 setNeedsCompositingUpdate(); |
| 1456 } | 1460 } |
| 1457 | 1461 |
| 1458 } // namespace blink | 1462 } // namespace blink |
| OLD | NEW |