| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 PassRefPtr<Image> createTransparentImage(const IntSize& size) | 97 PassRefPtr<Image> createTransparentImage(const IntSize& size) |
| 98 { | 98 { |
| 99 ASSERT(canCreateImageBuffer(size)); | 99 ASSERT(canCreateImageBuffer(size)); |
| 100 RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.widt
h(), size.height())); | 100 RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.widt
h(), size.height())); |
| 101 surface->getCanvas()->clear(SK_ColorTRANSPARENT); | 101 surface->getCanvas()->clear(SK_ColorTRANSPARENT); |
| 102 return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot())); | 102 return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot())); |
| 103 } | 103 } |
| 104 | 104 |
| 105 } // namespace | 105 } // namespace |
| 106 | 106 |
| 107 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver); | |
| 108 | |
| 109 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) | 107 inline HTMLCanvasElement::HTMLCanvasElement(Document& document) |
| 110 : HTMLElement(canvasTag, document) | 108 : HTMLElement(canvasTag, document) |
| 111 , DocumentVisibilityObserver(document) | 109 , DocumentVisibilityObserver(document) |
| 112 , m_size(DefaultWidth, DefaultHeight) | 110 , m_size(DefaultWidth, DefaultHeight) |
| 113 , m_ignoreReset(false) | 111 , m_ignoreReset(false) |
| 114 , m_accelerationDisabled(false) | |
| 115 , m_externallyAllocatedMemory(0) | 112 , m_externallyAllocatedMemory(0) |
| 116 , m_originClean(true) | 113 , m_originClean(true) |
| 117 , m_didFailToCreateImageBuffer(false) | 114 , m_didFailToCreateImageBuffer(false) |
| 118 , m_imageBufferIsClear(false) | 115 , m_imageBufferIsClear(false) |
| 119 { | 116 { |
| 120 setHasCustomStyleCallbacks(); | 117 setHasCustomStyleCallbacks(); |
| 121 } | 118 } |
| 122 | 119 |
| 123 DEFINE_NODE_FACTORY(HTMLCanvasElement) | 120 DEFINE_NODE_FACTORY(HTMLCanvasElement) |
| 124 | 121 |
| 125 HTMLCanvasElement::~HTMLCanvasElement() | 122 HTMLCanvasElement::~HTMLCanvasElement() |
| 126 { | 123 { |
| 127 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external
lyAllocatedMemory); | 124 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_external
lyAllocatedMemory); |
| 128 #if !ENABLE(OILPAN) | 125 #if !ENABLE(OILPAN) |
| 129 for (CanvasObserver* canvasObserver : m_observers) | |
| 130 canvasObserver->canvasDestroyed(this); | |
| 131 // Ensure these go away before the ImageBuffer. | 126 // Ensure these go away before the ImageBuffer. |
| 132 m_context.clear(); | 127 m_context.clear(); |
| 133 #endif | 128 #endif |
| 134 } | 129 } |
| 135 | 130 |
| 136 WebThread* HTMLCanvasElement::getToBlobThreadInstance() | 131 WebThread* HTMLCanvasElement::getToBlobThreadInstance() |
| 137 { | 132 { |
| 138 DEFINE_STATIC_LOCAL(OwnPtr<WebThread>, s_toBlobThread, ()); | 133 DEFINE_STATIC_LOCAL(OwnPtr<WebThread>, s_toBlobThread, ()); |
| 139 if (!s_toBlobThread) { | 134 if (!s_toBlobThread) { |
| 140 s_toBlobThread = adoptPtr(Platform::current()->createThread("Async toBlo
b")); | 135 s_toBlobThread = adoptPtr(Platform::current()->createThread("Async toBlo
b")); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 m_imageBuffer->setFilterQuality(filterQuality); | 169 m_imageBuffer->setFilterQuality(filterQuality); |
| 175 } | 170 } |
| 176 } | 171 } |
| 177 | 172 |
| 178 Node::InsertionNotificationRequest HTMLCanvasElement::insertedInto(ContainerNode
* node) | 173 Node::InsertionNotificationRequest HTMLCanvasElement::insertedInto(ContainerNode
* node) |
| 179 { | 174 { |
| 180 setIsInCanvasSubtree(true); | 175 setIsInCanvasSubtree(true); |
| 181 return HTMLElement::insertedInto(node); | 176 return HTMLElement::insertedInto(node); |
| 182 } | 177 } |
| 183 | 178 |
| 184 void HTMLCanvasElement::addObserver(CanvasObserver* observer) | |
| 185 { | |
| 186 m_observers.add(observer); | |
| 187 } | |
| 188 | |
| 189 void HTMLCanvasElement::removeObserver(CanvasObserver* observer) | |
| 190 { | |
| 191 m_observers.remove(observer); | |
| 192 } | |
| 193 | |
| 194 void HTMLCanvasElement::setHeight(int value) | 179 void HTMLCanvasElement::setHeight(int value) |
| 195 { | 180 { |
| 196 setIntegralAttribute(heightAttr, value); | 181 setIntegralAttribute(heightAttr, value); |
| 197 } | 182 } |
| 198 | 183 |
| 199 void HTMLCanvasElement::setWidth(int value) | 184 void HTMLCanvasElement::setWidth(int value) |
| 200 { | 185 { |
| 201 setIntegralAttribute(widthAttr, value); | 186 setIntegralAttribute(widthAttr, value); |
| 202 } | 187 } |
| 203 | 188 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 { | 276 { |
| 292 if (rect.isEmpty()) | 277 if (rect.isEmpty()) |
| 293 return; | 278 return; |
| 294 m_imageBufferIsClear = false; | 279 m_imageBufferIsClear = false; |
| 295 clearCopiedImage(); | 280 clearCopiedImage(); |
| 296 if (layoutObject()) | 281 if (layoutObject()) |
| 297 layoutObject()->setMayNeedPaintInvalidation(); | 282 layoutObject()->setMayNeedPaintInvalidation(); |
| 298 m_dirtyRect.unite(rect); | 283 m_dirtyRect.unite(rect); |
| 299 if (m_context && m_context->is2d() && hasImageBuffer()) | 284 if (m_context && m_context->is2d() && hasImageBuffer()) |
| 300 buffer()->didDraw(rect); | 285 buffer()->didDraw(rect); |
| 301 notifyObserversCanvasChanged(rect); | |
| 302 } | 286 } |
| 303 | 287 |
| 304 void HTMLCanvasElement::didFinalizeFrame() | 288 void HTMLCanvasElement::didFinalizeFrame() |
| 305 { | 289 { |
| 306 if (m_dirtyRect.isEmpty()) | 290 if (m_dirtyRect.isEmpty()) |
| 307 return; | 291 return; |
| 308 | 292 |
| 309 // Propagate the m_dirtyRect accumulated so far to the compositor | 293 // Propagate the m_dirtyRect accumulated so far to the compositor |
| 310 // before restarting with a blank dirty rect. | 294 // before restarting with a blank dirty rect. |
| 311 FloatRect srcRect(0, 0, size().width(), size().height()); | 295 FloatRect srcRect(0, 0, size().width(), size().height()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 mappedDirtyRect.move(-lb->contentBoxOffset()); | 332 mappedDirtyRect.move(-lb->contentBoxOffset()); |
| 349 } | 333 } |
| 350 m_imageBuffer->finalizeFrame(mappedDirtyRect); | 334 m_imageBuffer->finalizeFrame(mappedDirtyRect); |
| 351 } else { | 335 } else { |
| 352 m_imageBuffer->finalizeFrame(m_dirtyRect); | 336 m_imageBuffer->finalizeFrame(m_dirtyRect); |
| 353 } | 337 } |
| 354 } | 338 } |
| 355 ASSERT(m_dirtyRect.isEmpty()); | 339 ASSERT(m_dirtyRect.isEmpty()); |
| 356 } | 340 } |
| 357 | 341 |
| 358 void HTMLCanvasElement::notifyObserversCanvasChanged(const FloatRect& rect) | |
| 359 { | |
| 360 for (CanvasObserver* canvasObserver : m_observers) | |
| 361 canvasObserver->canvasChanged(this, rect); | |
| 362 } | |
| 363 | |
| 364 void HTMLCanvasElement::reset() | 342 void HTMLCanvasElement::reset() |
| 365 { | 343 { |
| 366 if (m_ignoreReset) | 344 if (m_ignoreReset) |
| 367 return; | 345 return; |
| 368 | 346 |
| 369 m_dirtyRect = FloatRect(); | 347 m_dirtyRect = FloatRect(); |
| 370 | 348 |
| 371 bool ok; | 349 bool ok; |
| 372 bool hadImageBuffer = hasImageBuffer(); | 350 bool hadImageBuffer = hasImageBuffer(); |
| 373 | 351 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 404 if (layoutObject->isCanvas()) { | 382 if (layoutObject->isCanvas()) { |
| 405 if (oldSize != size()) { | 383 if (oldSize != size()) { |
| 406 toLayoutHTMLCanvas(layoutObject)->canvasSizeChanged(); | 384 toLayoutHTMLCanvas(layoutObject)->canvasSizeChanged(); |
| 407 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) | 385 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) |
| 408 layoutBox()->contentChanged(CanvasChanged); | 386 layoutBox()->contentChanged(CanvasChanged); |
| 409 } | 387 } |
| 410 if (hadImageBuffer) | 388 if (hadImageBuffer) |
| 411 layoutObject->setShouldDoFullPaintInvalidation(); | 389 layoutObject->setShouldDoFullPaintInvalidation(); |
| 412 } | 390 } |
| 413 } | 391 } |
| 414 | |
| 415 for (CanvasObserver* canvasObserver : m_observers) | |
| 416 canvasObserver->canvasResized(this); | |
| 417 } | 392 } |
| 418 | 393 |
| 419 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const | 394 bool HTMLCanvasElement::paintsIntoCanvasBuffer() const |
| 420 { | 395 { |
| 421 ASSERT(m_context); | 396 ASSERT(m_context); |
| 422 | 397 |
| 423 if (!m_context->isAccelerated()) | 398 if (!m_context->isAccelerated()) |
| 424 return true; | 399 return true; |
| 425 | 400 |
| 426 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) | 401 if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 if (document().settings() && document().settings()->disableReadingFromCanvas
()) | 598 if (document().settings() && document().settings()->disableReadingFromCanvas
()) |
| 624 return false; | 599 return false; |
| 625 return m_originClean; | 600 return m_originClean; |
| 626 } | 601 } |
| 627 | 602 |
| 628 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const | 603 bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const |
| 629 { | 604 { |
| 630 if (m_context && !m_context->is2d()) | 605 if (m_context && !m_context->is2d()) |
| 631 return false; | 606 return false; |
| 632 | 607 |
| 633 if (m_accelerationDisabled) | |
| 634 return false; | |
| 635 | |
| 636 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) | 608 if (RuntimeEnabledFeatures::forceDisplayList2dCanvasEnabled()) |
| 637 return false; | 609 return false; |
| 638 | 610 |
| 639 Settings* settings = document().settings(); | 611 Settings* settings = document().settings(); |
| 640 if (!settings || !settings->accelerated2dCanvasEnabled()) | 612 if (!settings || !settings->accelerated2dCanvasEnabled()) |
| 641 return false; | 613 return false; |
| 642 | 614 |
| 643 int canvasPixelCount = size.width() * size.height(); | 615 int canvasPixelCount = size.width() * size.height(); |
| 644 | 616 |
| 645 if (RuntimeEnabledFeatures::displayList2dCanvasEnabled()) { | 617 if (RuntimeEnabledFeatures::displayList2dCanvasEnabled()) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 return true; | 660 return true; |
| 689 } | 661 } |
| 690 | 662 |
| 691 PassOwnPtr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(const
IntSize& deviceSize, int* msaaSampleCount) | 663 PassOwnPtr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(const
IntSize& deviceSize, int* msaaSampleCount) |
| 692 { | 664 { |
| 693 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque :
Opaque; | 665 OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque :
Opaque; |
| 694 | 666 |
| 695 *msaaSampleCount = 0; | 667 *msaaSampleCount = 0; |
| 696 if (is3D()) { | 668 if (is3D()) { |
| 697 // If 3d, but the use of the canvas will be for non-accelerated content | 669 // If 3d, but the use of the canvas will be for non-accelerated content |
| 698 // (such as -webkit-canvas, then then make a non-accelerated | 670 // then make a non-accelerated ImageBuffer. This means copying the inter
nal |
| 699 // ImageBuffer. This means copying the internal Image will require a | 671 // Image will require a pixel readback, but that is unavoidable in this
case. |
| 700 // pixel readback, but that is unavoidable in this case. | |
| 701 // FIXME: Actually, avoid setting m_accelerationDisabled at all when | |
| 702 // doing GPU-based rasterization. | |
| 703 if (m_accelerationDisabled) | |
| 704 return adoptPtr(new UnacceleratedImageBufferSurface(deviceSize, opac
ityMode)); | |
| 705 return adoptPtr(new AcceleratedImageBufferSurface(deviceSize, opacityMod
e)); | 672 return adoptPtr(new AcceleratedImageBufferSurface(deviceSize, opacityMod
e)); |
| 706 } | 673 } |
| 707 | 674 |
| 708 if (shouldAccelerate(deviceSize)) { | 675 if (shouldAccelerate(deviceSize)) { |
| 709 if (document().settings()) | 676 if (document().settings()) |
| 710 *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASam
pleCount(); | 677 *msaaSampleCount = document().settings()->accelerated2dCanvasMSAASam
pleCount(); |
| 711 OwnPtr<ImageBufferSurface> surface = adoptPtr(new Canvas2DImageBufferSur
face(deviceSize, *msaaSampleCount, opacityMode, Canvas2DLayerBridge::EnableAccel
eration)); | 678 OwnPtr<ImageBufferSurface> surface = adoptPtr(new Canvas2DImageBufferSur
face(deviceSize, *msaaSampleCount, opacityMode, Canvas2DLayerBridge::EnableAccel
eration)); |
| 712 if (surface->isValid()) | 679 if (surface->isValid()) |
| 713 return surface.release(); | 680 return surface.release(); |
| 714 } | 681 } |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 { | 946 { |
| 980 return FloatSize(width(), height()); | 947 return FloatSize(width(), height()); |
| 981 } | 948 } |
| 982 | 949 |
| 983 bool HTMLCanvasElement::isOpaque() const | 950 bool HTMLCanvasElement::isOpaque() const |
| 984 { | 951 { |
| 985 return m_context && !m_context->hasAlpha(); | 952 return m_context && !m_context->hasAlpha(); |
| 986 } | 953 } |
| 987 | 954 |
| 988 } // blink | 955 } // blink |
| OLD | NEW |