void FEComponentTransfer::applySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return; unsigned char rValues[256], gValues[256], bValues[256], aValues[256]; getValues(rValues, gValues, bValues, aValues); IntRect destRect = drawingRegionOfInputImage(in->absolutePaintRect()); SkPaint paint; paint.setColorFilter(SkTableColorFilter::CreateARGB(aValues, rValues, gValues, bValues))->unref(); paint.setXfermodeMode(SkXfermode::kSrc_Mode); resultImage->context()->drawBitmap(nativeImage->bitmap(), destRect.x(), destRect.y(), &paint); if (affectsTransparentPixels()) { IntRect fullRect = IntRect(IntPoint(), absolutePaintRect().size()); resultImage->context()->clipOut(destRect); resultImage->context()->fillRect(fullRect, Color(rValues[0], gValues[0], bValues[0], aValues[0])); } }
void FEColorMatrix::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; FilterEffect* in = inputEffect(0); IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); SkAutoTUnref<SkColorFilter> filter(createColorFilter(m_type, m_values.data())); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return; SkPaint paint; paint.setColorFilter(filter); paint.setXfermodeMode(SkXfermode::kSrc_Mode); resultImage->context()->drawBitmap(nativeImage->bitmap(), drawingRegion.x(), drawingRegion.y(), &paint); if (affectsTransparentPixels()) { IntRect fullRect = IntRect(IntPoint(), absolutePaintRect().size()); resultImage->context()->clipOut(drawingRegion); resultImage->context()->fillRect(fullRect, Color(m_values[4], m_values[9], m_values[14], m_values[19])); } return; }
void FEImage::platformApplySoftware() { RenderObject* renderer = referencedRenderer(); if (!m_image && !renderer) return; ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; SVGFilter* svgFilter = static_cast<SVGFilter*>(filter()); FloatRect destRect = svgFilter->absoluteTransform().mapRect(filterPrimitiveSubregion()); FloatRect srcRect; if (renderer) srcRect = svgFilter->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); else { srcRect = FloatRect(FloatPoint(), m_image->size()); m_preserveAspectRatio.transformRect(destRect, srcRect); } IntPoint paintLocation = absolutePaintRect().location(); destRect.move(-paintLocation.x(), -paintLocation.y()); // FEImage results are always in ColorSpaceDeviceRGB setResultColorSpace(ColorSpaceDeviceRGB); if (renderer) { const AffineTransform& absoluteTransform = svgFilter->absoluteTransform(); resultImage->context()->concatCTM(absoluteTransform); SVGElement* contextNode = static_cast<SVGElement*>(renderer->node()); if (contextNode->isStyled() && static_cast<SVGStyledElement*>(contextNode)->hasRelativeLengths()) { SVGLengthContext lengthContext(contextNode); float width = 0; float height = 0; // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport. // Build up a transformation that maps from the viewport space to the filter primitive subregion. if (lengthContext.determineViewport(width, height)) resultImage->context()->concatCTM(makeMapBetweenRects(FloatRect(0, 0, width, height), destRect)); } AffineTransform contentTransformation; SVGRenderingContext::renderSubtreeToImageBuffer(resultImage, renderer, contentTransformation); return; } resultImage->context()->drawImage(m_image.get(), ColorSpaceDeviceRGB, destRect, srcRect); }
void FEMorphology::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; FilterEffect* in = inputEffect(0); IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); setIsAlphaImage(in->isAlphaImage()); float radiusX = filter()->applyHorizontalScale(m_radiusX); float radiusY = filter()->applyVerticalScale(m_radiusY); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); SkPaint paint; GraphicsContext* dstContext = resultImage->context(); if (m_type == FEMORPHOLOGY_OPERATOR_DILATE) paint.setImageFilter(SkDilateImageFilter::Create(radiusX, radiusY))->unref(); else if (m_type == FEMORPHOLOGY_OPERATOR_ERODE) paint.setImageFilter(SkErodeImageFilter::Create(radiusX, radiusY))->unref(); SkRect bounds = SkRect::MakeWH(absolutePaintRect().width(), absolutePaintRect().height()); dstContext->saveLayer(&bounds, &paint); dstContext->drawImage(image.get(), drawingRegion.location(), CompositeCopy); dstContext->restoreLayer(); }
void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context, DrawingBuffer*) { HTMLCanvasElement* canvas = context->canvas(); ImageBuffer* imageBuffer = canvas->buffer(); int rowBytes = m_currentWidth * 4; int totalBytes = rowBytes * m_currentHeight; OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]); if (!pixels) return; readRenderingResults(pixels.get(), totalBytes); if (!m_attrs.premultipliedAlpha) { for (int i = 0; i < totalBytes; i += 4) { // Premultiply alpha. pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); } } paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, canvas->width(), canvas->height(), imageBuffer->context()->platformContext()); }
void FEDropShadow::applySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Filter* filter = this->filter(); FloatSize blurRadius(filter->applyHorizontalScale(m_stdX), filter->applyVerticalScale(m_stdY)); FloatSize offset(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); GraphicsContext* resultContext = resultImage->context(); ASSERT(resultContext); Color color = adaptColorToOperatingColorSpace(m_shadowColor.combineWithAlpha(m_shadowOpacity)); SkAutoTUnref<SkImageFilter> blurFilter(SkBlurImageFilter::Create(blurRadius.width(), blurRadius.height())); SkAutoTUnref<SkColorFilter> colorFilter(SkColorFilter::CreateModeFilter(color.rgb(), SkXfermode::kSrcIn_Mode)); SkPaint paint; paint.setImageFilter(blurFilter.get()); paint.setColorFilter(colorFilter.get()); paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return; resultContext->drawBitmap(nativeImage->bitmap(), drawingRegion.x() + offset.width(), drawingRegion.y() + offset.height(), &paint); resultContext->drawBitmap(nativeImage->bitmap(), drawingRegion.x(), drawingRegion.y()); }
void FEGaussianBlur::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; FilterEffect* in = inputEffect(0); IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); setIsAlphaImage(in->isAlphaImage()); float stdX = filter()->applyHorizontalScale(m_stdX); float stdY = filter()->applyVerticalScale(m_stdY); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); SkPaint paint; GraphicsContext* dstContext = resultImage->context(); paint.setImageFilter(SkBlurImageFilter::Create(stdX, stdY))->unref(); SkRect bounds = SkRect::MakeWH(absolutePaintRect().width(), absolutePaintRect().height()); dstContext->saveLayer(&bounds, &paint); paint.setColor(0xFFFFFFFF); dstContext->drawImage(image.get(), drawingRegion.location(), CompositeCopy); dstContext->restoreLayer(); }
bool FEBlend::platformApplySkia() { // For now, only use the skia implementation for accelerated rendering. if (filter()->renderingMode() != Accelerated) return false; FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); if (!in || !in2) return false; ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return false; RefPtr<Image> foreground = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<Image> background = in2->asImageBuffer()->copyImage(DontCopyBackingStore); SkBitmap foregroundBitmap = foreground->nativeImageForCurrentFrame()->bitmap(); SkBitmap backgroundBitmap = background->nativeImageForCurrentFrame()->bitmap(); SkAutoTUnref<SkImageFilter> backgroundSource(new SkBitmapSource(backgroundBitmap)); SkBlendImageFilter::Mode mode = toSkiaMode(m_mode); SkAutoTUnref<SkImageFilter> blend(new SkBlendImageFilter(mode, backgroundSource)); SkPaint paint; paint.setImageFilter(blend); SkCanvas* canvas = resultImage->context()->platformContext()->canvas(); canvas->drawBitmap(foregroundBitmap, 0, 0, &paint); return true; }
bool FELighting::applySkia() { // For now, only use the skia implementation for accelerated rendering. if (!filter()->isAccelerated()) return false; ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return false; FilterEffect* in = inputEffect(0); IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); setIsAlphaImage(in->isAlphaImage()); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return false; GraphicsContext* dstContext = resultImage->context(); SkPaint paint; RefPtr<SkImageFilter> filter = createImageFilter(0); paint.setImageFilter(filter.get()); dstContext->drawBitmap(nativeImage->bitmap(), drawingRegion.location().x(), drawingRegion.location().y(), &paint); return true; }
bool GraphicsContext3DInternal::paintCompositedResultsToCanvas(CanvasRenderingContext* context) { LOGWEBGL("paintCompositedResultsToCanvas()"); ImageBuffer* imageBuffer = context->canvas()->buffer(); const SkBitmap& canvasBitmap = imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false); SkCanvas canvas(canvasBitmap); MutexLocker lock(m_fboMutex); FBO* fbo = m_frontFBO; if (!fbo) return false; SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height, fbo->bytesPerRow()); unsigned char* bits = NULL; if (fbo->lockGraphicBuffer((void**)&bits)) { bitmap.setPixels(bits); SkRect dstRect; dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height()); canvas.save(); canvas.translate(0, SkIntToScalar(imageBuffer->size().height())); canvas.scale(SK_Scalar1, -SK_Scalar1); canvas.drawBitmapRect(bitmap, 0, dstRect); canvas.restore(); bitmap.setPixels(0); fbo->unlockGraphicBuffer(); } return true; }
void FEColorMatrix::platformApplySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); IntRect imageRect(IntPoint(), absolutePaintRect().size()); RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect); switch (m_type) { case FECOLORMATRIX_TYPE_UNKNOWN: break; case FECOLORMATRIX_TYPE_MATRIX: effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), m_values); break; case FECOLORMATRIX_TYPE_SATURATE: effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), m_values); break; case FECOLORMATRIX_TYPE_HUEROTATE: effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), m_values); break; case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), m_values); setIsAlphaImage(true); break; } resultImage->putByteArray(Unmultiplied, pixelArray.get(), imageRect.size(), imageRect, IntPoint()); }
void FEGaussianBlur::platformApplySkia() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; FilterEffect* in = inputEffect(0); IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); setIsAlphaImage(in->isAlphaImage()); float stdX = filter()->applyHorizontalScale(m_stdX); float stdY = filter()->applyVerticalScale(m_stdY); RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); SkPaint paint; GraphicsContext* dstContext = resultImage->context(); SkCanvas* canvas = dstContext->platformContext()->canvas(); paint.setImageFilter(new SkBlurImageFilter(stdX, stdY))->unref(); canvas->saveLayer(0, &paint); paint.setColor(0xFFFFFFFF); dstContext->drawImage(image.get(), ColorSpaceDeviceRGB, drawingRegion.location(), CompositeCopy); canvas->restore(); return; }
void FEFlood::platformApplySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity()); resultImage->context()->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, ColorSpaceDeviceRGB); }
void SourceGraphic::platformApplySoftware() { ImageBuffer* resultImage = createImageBufferResult(); Filter* filter = this->filter(); if (!resultImage || !filter->sourceImage()) return; resultImage->context()->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint()); }
void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context) { HTMLCanvasElement* canvas = context->canvas(); ImageBuffer* imageBuffer = canvas->buffer(); unsigned char* pixels = 0; #if PLATFORM(SKIA) const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap(); const SkBitmap* readbackBitmap = 0; ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_impl->height()) { // This is the fastest and most common case. We read back // directly into the canvas's backing store. readbackBitmap = canvasBitmap; m_resizingBitmap.reset(); } else { // We need to allocate a temporary bitmap for reading back the // pixel data. We will then use Skia to rescale this bitmap to // the size of the canvas's backing store. if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.height() != m_impl->height()) { m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, m_impl->width(), m_impl->height()); if (!m_resizingBitmap.allocPixels()) return; } readbackBitmap = &m_resizingBitmap; } // Read back the frame buffer. SkAutoLockPixels bitmapLock(*readbackBitmap); pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); #elif PLATFORM(CG) if (m_renderOutput) pixels = m_renderOutput; #else #error Must port to your platform #endif m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height()); #if PLATFORM(SKIA) if (m_resizingBitmap.readyToDraw()) { // We need to draw the resizing bitmap into the canvas's backing store. SkCanvas canvas(*canvasBitmap); SkRect dst; dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->width()), SkIntToScalar(canvasBitmap->height())); canvas.drawBitmapRect(m_resizingBitmap, 0, dst); } #elif PLATFORM(CG) if (m_renderOutput && context->is3d()) { WebGLRenderingContext* webGLContext = static_cast<WebGLRenderingContext*>(context); webGLContext->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(), canvas->width(), canvas->height(), imageBuffer->context()->platformContext()); } #else #error Must port to your platform #endif }
void FEFlood::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Color color = floodColor().combineWithAlpha(floodOpacity()); resultImage->context()->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color); FilterEffect::setResultColorSpace(ColorSpaceDeviceRGB); }
void FEDropShadow::platformApplySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Filter& filter = this->filter(); FloatSize blurRadius(2 * filter.applyHorizontalScale(m_stdX), 2 * filter.applyVerticalScale(m_stdY)); blurRadius.scale(filter.filterScale()); FloatSize offset(filter.applyHorizontalScale(m_dx), filter.applyVerticalScale(m_dy)); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); FloatRect drawingRegionWithOffset(drawingRegion); drawingRegionWithOffset.move(offset); ImageBuffer* sourceImage = in->asImageBuffer(); if (!sourceImage) return; GraphicsContext& resultContext = resultImage->context(); resultContext.setAlpha(m_shadowOpacity); resultContext.drawImageBuffer(*sourceImage, drawingRegionWithOffset); resultContext.setAlpha(1); ShadowBlur contextShadow(blurRadius, offset, m_shadowColor); // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData. IntRect shadowArea(IntPoint(), resultImage->internalSize()); RefPtr<Uint8ClampedArray> srcPixelArray = resultImage->getPremultipliedImageData(shadowArea, ImageBuffer::BackingStoreCoordinateSystem); contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width()); resultImage->putByteArray(Premultiplied, srcPixelArray.get(), shadowArea.size(), shadowArea, IntPoint(), ImageBuffer::BackingStoreCoordinateSystem); resultContext.setCompositeOperation(CompositeSourceIn); resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor); resultContext.setCompositeOperation(CompositeDestinationOver); resultImage->context().drawImageBuffer(*sourceImage, drawingRegion); }
void FEComposite::platformApplySoftware() { FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) { ByteArray* dstPixelArray = createPremultipliedImageResult(); if (!dstPixelArray) return; IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<ByteArray> srcPixelArray = in->asPremultipliedImage(effectADrawingRect); IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); in2->copyPremultipliedImage(dstPixelArray, effectBDrawingRect); arithmetic(srcPixelArray.get(), dstPixelArray, m_k1, m_k2, m_k3, m_k4); return; } ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext* filterContext = resultImage->context(); FloatRect srcRect = FloatRect(0, 0, -1, -1); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); break; case FECOMPOSITE_OPERATOR_IN: { GraphicsContextStateSaver stateSaver(*filterContext); filterContext->clipToImageBuffer(in2->asImageBuffer(), drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); break; } case FECOMPOSITE_OPERATOR_OUT: filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR); break; default: break; } }
void FEDropShadow::platformApplySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; Filter* filter = this->filter(); FloatSize blurRadius(filter->applyHorizontalScale(m_stdX), filter->applyVerticalScale(m_stdY)); FloatSize offset(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); FloatRect drawingRegionWithOffset(drawingRegion); drawingRegionWithOffset.move(offset); ImageBuffer* sourceImage = in->asImageBuffer(); ASSERT(sourceImage); GraphicsContext* resultContext = resultImage->context(); ASSERT(resultContext); resultContext->setAlpha(m_shadowOpacity); resultContext->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegionWithOffset); resultContext->setAlpha(1); ShadowBlur contextShadow(blurRadius, offset, m_shadowColor, ColorSpaceDeviceRGB); // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData. IntRect shadowArea(IntPoint(), resultImage->size()); RefPtr<ByteArray> srcPixelArray = resultImage->getPremultipliedImageData(shadowArea); contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width()); resultImage->putPremultipliedImageData(srcPixelArray.get(), shadowArea.size(), shadowArea, IntPoint()); resultContext->setCompositeOperation(CompositeSourceIn); resultContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor, ColorSpaceDeviceRGB); resultContext->setCompositeOperation(CompositeDestinationOver); resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegion); }
void SourceAlpha::platformApplySoftware() { ImageBuffer* resultImage = createImageBufferResult(); Filter* filter = this->filter(); if (!resultImage || !filter->sourceImage()) return; setIsAlphaImage(true); FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); GraphicsContext* filterContext = resultImage->context(); filterContext->fillRect(imageRect, Color::black, ColorSpaceDeviceRGB); filterContext->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint(), CompositeDestinationIn); }
PassRefPtr<Image> WebCLHTMLUtil::videoFrameToImage(HTMLVideoElement* video) { if (!video || !video->clientWidth() || !video->clientHeight()) return nullptr; IntSize size(video->clientWidth(), video->clientHeight()); ImageBuffer* imageBufferObject = m_generatedImageCache.imageBuffer(size); if (!imageBufferObject) return nullptr; IntRect destRect(0, 0, size.width(), size.height()); video->paintCurrentFrameInContext(imageBufferObject->context(), destRect); return imageBufferObject->copyImage(); }
void FEMerge::platformApplySoftware() { unsigned size = numberOfEffectInputs(); ASSERT(size > 0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext* filterContext = resultImage->context(); for (unsigned i = 0; i < size; ++i) { FilterEffect* in = inputEffect(i); filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); } }
void FEOffset::applySoftware() { FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; setIsAlphaImage(in->isAlphaImage()); FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); Filter* filter = this->filter(); drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); resultImage->context()->drawImageBuffer(in->asImageBuffer(), drawingRegion); }
void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context) { HTMLCanvasElement* canvas = context->canvas(); ImageBuffer* imageBuffer = canvas->buffer(); int rowBytes = m_currentWidth * 4; int totalBytes = rowBytes * m_currentHeight; OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]); if (!pixels) return; makeContextCurrent(); bool mustRestoreFBO = false; if (m_attrs.antialias) { ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); mustRestoreFBO = true; } else { if (m_boundFBO != m_fbo) { mustRestoreFBO = true; ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); } } GLint packAlignment = 4; bool mustRestorePackAlignment = false; ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); if (packAlignment > 4) { ::glPixelStorei(GL_PACK_ALIGNMENT, 4); mustRestorePackAlignment = true; } ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get()); if (mustRestorePackAlignment) ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); if (mustRestoreFBO) ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight, canvas->width(), canvas->height(), imageBuffer->context()->platformContext()); }
void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context) { LOGWEBGL("paintRenderingResultsToCanvas()"); ImageBuffer* imageBuffer = context->canvas()->buffer(); const SkBitmap& canvasBitmap = imageBuffer->context()->platformContext()->recordingCanvas()->getDevice()->accessBitmap(false); SkCanvas canvas(canvasBitmap); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_width, m_height); bitmap.allocPixels(); unsigned char *pixels = static_cast<unsigned char*>(bitmap.getPixels()); glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); SkRect dstRect; dstRect.iset(0, 0, imageBuffer->size().width(), imageBuffer->size().height()); canvas.drawBitmapRect(bitmap, 0, dstRect); }
void FEImage::platformApplySoftware() { if (!m_image.get()) return; ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; FloatRect srcRect(FloatPoint(), m_image->size()); FloatRect destRect(m_absoluteSubregion); m_preserveAspectRatio.transformRect(destRect, srcRect); IntPoint paintLocation = absolutePaintRect().location(); destRect.move(-paintLocation.x(), -paintLocation.y()); resultImage->context()->drawImage(m_image.get(), ColorSpaceDeviceRGB, destRect, srcRect); }
void FEBlend::platformApplySoftware() { FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return; GraphicsContext& filterContext = resultImage->context(); ImageBuffer* imageBuffer = in->asImageBuffer(); ImageBuffer* imageBuffer2 = in2->asImageBuffer(); ASSERT(imageBuffer); ASSERT(imageBuffer2); filterContext.drawImageBuffer(imageBuffer2, ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext.drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), IntRect(IntPoint(), imageBuffer->logicalSize()), ImagePaintingOptions(CompositeSourceOver, m_mode)); }
void FETile::platformApplySoftware() { // FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise. FilterEffect* in = inputEffect(0); ImageBuffer* resultImage = createImageBufferResult(); ImageBuffer* inBuffer = in->asImageBuffer(); if (!resultImage || !inBuffer) return; setIsAlphaImage(in->isAlphaImage()); // Source input needs more attention. It has the size of the filterRegion but gives the // size of the cutted sourceImage back. This is part of the specification and optimization. FloatRect tileRect = in->maxEffectRect(); FloatPoint inMaxEffectLocation = tileRect.location(); FloatPoint maxEffectLocation = maxEffectRect().location(); if (in->filterEffectType() == FilterEffectTypeSourceInput) { Filter& filter = this->filter(); tileRect = filter.filterRegion(); tileRect.scale(filter.filterResolution().width(), filter.filterResolution().height()); } auto tileImage = SVGRenderingContext::createImageBuffer(tileRect, tileRect, ColorSpaceSRGB, filter().renderingMode()); if (!tileImage) return; GraphicsContext& tileImageContext = tileImage->context(); tileImageContext.translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); tileImageContext.drawImageBuffer(*inBuffer, in->absolutePaintRect().location()); auto tileImageCopy = ImageBuffer::sinkIntoImage(WTFMove(tileImage)); if (!tileImageCopy) return; auto pattern = Pattern::create(WTFMove(tileImageCopy), true, true); AffineTransform patternTransform; patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); pattern.get().setPatternSpaceTransform(patternTransform); GraphicsContext& filterContext = resultImage->context(); filterContext.setFillPattern(WTFMove(pattern)); filterContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); }
void SourceAlpha::applySoftware() { ImageBuffer* resultImage = createImageBufferResult(); Filter* filter = this->filter(); if (!resultImage || !filter->sourceImage()) return; setIsAlphaImage(true); FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); GraphicsContext* filterContext = resultImage->context(); filterContext->fillRect(imageRect, Color::black); IntRect srcRect = filter->sourceImageRect(); if (ImageBuffer* sourceImageBuffer = filter->sourceImage()) { filterContext->drawImageBuffer(sourceImageBuffer, FloatRect(IntPoint(srcRect.location() - absolutePaintRect().location()), sourceImageBuffer->size()), 0, CompositeDestinationIn); } }
bool FEDisplacementMap::applySkia() { // For now, only use the skia implementation for accelerated rendering. if (!filter()->isAccelerated()) return false; FilterEffect* in = inputEffect(0); FilterEffect* in2 = inputEffect(1); if (!in || !in2) return false; ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) return false; RefPtr<Image> color = in->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<Image> displ = in2->asImageBuffer()->copyImage(DontCopyBackingStore); RefPtr<NativeImageSkia> colorNativeImage = color->nativeImageForCurrentFrame(); RefPtr<NativeImageSkia> displNativeImage = displ->nativeImageForCurrentFrame(); if (!colorNativeImage || !displNativeImage) return false; SkBitmap colorBitmap = colorNativeImage->bitmap(); SkBitmap displBitmap = displNativeImage->bitmap(); SkAutoTUnref<SkImageFilter> colorSource(new SkBitmapSource(colorBitmap)); SkAutoTUnref<SkImageFilter> displSource(new SkBitmapSource(displBitmap)); SkDisplacementMapEffect::ChannelSelectorType typeX = toSkiaMode(m_xChannelSelector); SkDisplacementMapEffect::ChannelSelectorType typeY = toSkiaMode(m_yChannelSelector); // FIXME : Only applyHorizontalScale is used and applyVerticalScale is ignored // This can be fixed by adding a 2nd scale parameter to SkDisplacementMapEffect SkAutoTUnref<SkImageFilter> displEffect(new SkDisplacementMapEffect( typeX, typeY, SkFloatToScalar(filter()->applyHorizontalScale(m_scale)), displSource, colorSource)); SkPaint paint; paint.setImageFilter(displEffect); resultImage->context()->drawBitmap(colorBitmap, 0, 0, &paint); return true; }