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 |