GraphicsContext* HTMLCanvasElement::existingDrawingContext() const { if (!hasImageBuffer()) return 0; return drawingContext(); }
void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r) { if (m_context) { if (!paintsIntoCanvasBuffer()) return; m_context->paintRenderingResultsToCanvas(); } if (hasImageBuffer()) { ImageBuffer* imageBuffer = buffer(); if (imageBuffer) { CompositeOperator compositeOperator = !m_context || m_context->hasAlpha() ? CompositeSourceOver : CompositeCopy; if (m_presentedImage) context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r), compositeOperator, DoNotRespectImageOrientation); else context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), 0, compositeOperator); } } else { // When alpha is false, we should draw to opaque black. if (m_context && !m_context->hasAlpha()) context->fillRect(FloatRect(r), Color(0, 0, 0)); } if (is3D()) toWebGLRenderingContext(m_context.get())->markLayerComposited(); }
PassRefPtr<Image> blink::CanvasRenderingContext2D::getImage( AccelerationHint hint, SnapshotReason reason) const { if (!hasImageBuffer()) return nullptr; return canvas()->buffer()->newImageSnapshot(hint, reason); }
void HTMLCanvasElement::reset() { if (m_ignoreReset) return; resetDirtyRect(); bool ok; bool hadImageBuffer = hasImageBuffer(); int w = getAttribute(widthAttr).toInt(&ok); if (!ok || w < 0) w = DefaultWidth; int h = getAttribute(heightAttr).toInt(&ok); if (!ok || h < 0) h = DefaultHeight; if (m_contextStateSaver) { // Reset to the initial graphics context state. m_contextStateSaver->restore(); m_contextStateSaver->save(); } if (m_context && m_context->is2d()) toCanvasRenderingContext2D(m_context.get())->reset(); IntSize oldSize = size(); IntSize newSize(w, h); // If the size of an existing buffer matches, we can just clear it instead of reallocating. // This optimization is only done for 2D canvases for now. if (hadImageBuffer && oldSize == newSize && m_context && m_context->is2d()) { if (!m_didClearImageBuffer) clearImageBuffer(); return; } setSurfaceSize(newSize); if (m_context && m_context->is3d() && oldSize != size()) toWebGLRenderingContext(m_context.get())->reshape(width(), height()); if (RenderObject* renderer = this->renderer()) { if (renderer->isCanvas()) { if (oldSize != size()) { toRenderHTMLCanvas(renderer)->canvasSizeChanged(); if (renderBox() && renderBox()->hasAcceleratedCompositing()) renderBox()->contentChanged(CanvasChanged); } if (hadImageBuffer) renderer->setShouldDoFullPaintInvalidation(true); } } WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator end = m_observers.end(); for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it) (*it)->canvasResized(this); }
void HTMLCanvasElement::ensureUnacceleratedImageBuffer() { if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCreateImageBuffer) return; discardImageBuffer(); OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque; m_imageBuffer = ImageBuffer::create(size(), opacityMode); m_didFailToCreateImageBuffer = !m_imageBuffer; }
void HTMLCanvasElement::didProcessTask() { // This method gets invoked if didDraw was called earlier in the current task. ASSERT(!m_dirtyRect.isEmpty()); if (is3D()) { didFinalizeFrame(); } else { ASSERT(hasImageBuffer()); m_imageBuffer->finalizeFrame(m_dirtyRect); } ASSERT(m_dirtyRect.isEmpty()); }
void HTMLCanvasElement::clearImageBuffer() { ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); ASSERT(!m_didClearImageBuffer); ASSERT(m_context); m_didClearImageBuffer = true; if (m_context->is2d()) { // No need to undo transforms/clip/etc. because we are called right // after the context is reset. toCanvasRenderingContext2D(m_context.get())->clearRect(0, 0, width(), height()); } }
AffineTransform HTMLCanvasElement::baseTransform() const { ASSERT(hasImageBuffer() && !m_didFailToCreateImageBuffer); return m_imageBuffer->baseTransform(); }
ImageBuffer* HTMLCanvasElement::buffer() const { if (!hasImageBuffer() && !m_didFailToCreateImageBuffer) const_cast<HTMLCanvasElement*>(this)->createImageBuffer(); return m_imageBuffer.get(); }