WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-207221-20200204132224.patch (text/plain), 468.07 KB, created by
Said Abou-Hallawa
on 2020-02-04 13:22:26 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Said Abou-Hallawa
Created:
2020-02-04 13:22:26 PST
Size:
468.07 KB
patch
obsolete
>Subversion Revision: 255620 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index fcf4f1502b713b9ef2e74652bd80ae92477789e7..1088f8931db868d5c86176487113c48b3dfb3c3b 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,485 @@ >+2020-02-04 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Implement the remote RenderingBackend >+ https://bugs.webkit.org/show_bug.cgi?id=207198 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Extend RenderingMode to include new enum values for creating remote >+ ImageBuffer types. >+ >+ * platform/graphics/RenderingBackend.cpp: >+ (WebCore::RenderingBackend::createImageBuffer): >+ * platform/graphics/RenderingBackend.h: >+ * platform/graphics/RenderingMode.h: >+ >+2020-02-03 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Introduce RenderingBackend and make it the creator of ImageBuffer >+ https://bugs.webkit.org/show_bug.cgi?id=207134 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ RenderingBackend will be responsible for creating the ImageBuffer. In a >+ following patch RemoteRenderingBackend will be introduced. It'll inherit >+ RenderingBackend and live in WebKit. It will be responsible for creating >+ the RemoteImageBuffer. The goal for RenderingBackend and RemoteRenderingBackend >+ is to interact with RemoteImageBuffer seamlessly in the caller side. >+ >+ * Headers.cmake: >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * page/Chrome.cpp: >+ (WebCore::Chrome::sharedRenderingBackend const): >+ * page/Chrome.h: >+ * page/ChromeClient.h: >+ (WebCore::ChromeClient::createRenderingBackend const): >+ * platform/HostWindow.h: >+ * platform/graphics/ContextualImageBuffer.h: >+ * platform/graphics/ImageBuffer.cpp: >+ (WebCore::ImageBuffer::create): >+ * platform/graphics/RenderingBackend.cpp: Added. >+ (WebCore::RenderingBackend::create): >+ (WebCore::RenderingBackend::sharedRenderingBackend): >+ (WebCore::RenderingBackend::createImageBuffer): >+ * platform/graphics/RenderingBackend.h: Added. >+ >+2020-02-02 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Create a new ImageBuffer type for drawing on a DisplayList >+ https://bugs.webkit.org/show_bug.cgi?id=207109 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ DisplayListImageBuffer inherits ImageBuffer and DrawingContext. The >+ drawing context will be the context of the display list. The ImageBuffer >+ operations will ensure the recorded display-list is replayed back before >+ getting the pixels of the ImageBufferBackend. >+ >+ * WebCore.xcodeproj/project.pbxproj: >+ * html/HTMLCanvasElement.cpp: >+ (WebCore::HTMLCanvasElement::createContext2d): >+ (WebCore::HTMLCanvasElement::setUsesDisplayListDrawing): >+ (WebCore::HTMLCanvasElement::setTracksDisplayListReplay): >+ (WebCore::HTMLCanvasElement::displayListAsText const): >+ (WebCore::HTMLCanvasElement::replayDisplayListAsText const): >+ (WebCore::HTMLCanvasElement::createImageBuffer const): >+ * html/HTMLCanvasElement.h: >+ * platform/graphics/ContextualImageBuffer.h: >+ (WebCore::ContextualImageBuffer::create): >+ (WebCore::ContextualImageBuffer::flushContext): >+ (WebCore::ContextualImageBuffer::copyNativeImage): >+ (WebCore::ContextualImageBuffer::copyImage): >+ (WebCore::ContextualImageBuffer::draw): >+ (WebCore::ContextualImageBuffer::drawPattern): >+ (WebCore::ContextualImageBuffer::sinkIntoNativeImage): >+ (WebCore::ContextualImageBuffer::sinkIntoImage): >+ (WebCore::ContextualImageBuffer::drawConsuming): >+ (WebCore::ContextualImageBuffer::convertToLuminanceMask): >+ (WebCore::ContextualImageBuffer::transformColorSpace): >+ * platform/graphics/DisplayListImageBuffer.h: Added. >+ (WebCore::DisplayListImageBuffer::create): >+ (WebCore::DisplayListImageBuffer::DisplayListImageBuffer): >+ (WebCore::DisplayListImageBuffer::~DisplayListImageBuffer): >+ * platform/graphics/ImageBuffer.cpp: >+ (WebCore::ImageBuffer::create): >+ * platform/graphics/ImageBuffer.h: >+ (WebCore::ImageBuffer::drawingContext): >+ (WebCore::ImageBuffer::flushDrawingContext): >+ * platform/graphics/PlatformImageBuffer.h: >+ * platform/graphics/RenderingMode.h: >+ * platform/graphics/displaylists/DisplayListDrawingContext.h: Added. >+ (WebCore::DisplayList::DrawingContext::DrawingContext): >+ (WebCore::DisplayList::DrawingContext::context const): >+ (WebCore::DisplayList::DrawingContext::displayList): >+ (WebCore::DisplayList::DrawingContext::displayList const): >+ (WebCore::DisplayList::DrawingContext::replayDisplayList const): >+ (WebCore::DisplayList::DrawingContext::setTracksDisplayListReplay): >+ (WebCore::DisplayList::DrawingContext::replayDisplayList): >+ >+2020-01-31 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Allow different back-ends for ImageBuffer >+ https://bugs.webkit.org/show_bug.cgi?id=207048 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ ImageBuffer will be re-factored to decouple the platform specifics and >+ the back-end details from the interface "ImageBuffer". >+ >+ A class hierarchy for the ImageBufferBackend will added to allow code >+ sharing and to split the code according to the platform and the back-end >+ details. >+ >+ ImageBuffer will be kept interface with the rest of the code but different >+ back-ends will be created. ContextualImageBuffer is a template class which >+ inherits ImageBuffer and will act as a bridge to the concrete >+ ImageBufferBackend. >+ >+ Based on the RenderingMode, a ContextualImageBuffer<BackendType> will >+ be created. Instead of checking the renderingMode in many places of the >+ code and instead of and using preprocessor directives, all these decisions >+ will be made in the concrete ImageBufferBackend. >+ >+ This re-factoring will allow creating new types of ImageBuffers backed by >+ new ImageBufferBackends. These new ImageBufferBackends will implement >+ DisplayList drawing and synchronize remote rendering. >+ >+ * Headers.cmake: >+ * PlatformAppleWin.cmake: >+ * PlatformFTW.cmake: >+ * PlatformMac.cmake: >+ * PlatformWin.cmake: >+ * Sources.txt: >+ * SourcesCocoa.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * html/CanvasBase.cpp: >+ (WebCore::CanvasBase::setImageBuffer const): >+ * platform/Cairo.cmake: >+ * platform/SourcesCairo.txt: >+ * platform/graphics/BitmapImage.cpp: >+ >+ (WebCore::BitmapImage::nativeImageForCurrentFrameRespectingOrientation): >+ * platform/graphics/ContextualImageBuffer.h: Added. >+ (WebCore::ContextualImageBuffer::create): >+ (WebCore::ContextualImageBuffer::ContextualImageBuffer): >+ (WebCore::ContextualImageBuffer::ensureBackend const): >+ (WebCore::ContextualImageBuffer::putImageData): >+ A bridge class to ImageBufferBackend. >+ >+ * platform/graphics/ImageBuffer.cpp: >+ (WebCore::ImageBuffer::create): >+ (WebCore::ImageBuffer::createCompatibleBuffer): >+ (WebCore::ImageBuffer::sizeNeedsClamping): >+ (WebCore::ImageBuffer::compatibleBufferSize): >+ (WebCore::ImageBuffer::sinkIntoNativeImage): >+ (WebCore::ImageBuffer::sinkIntoImage): >+ (WebCore::ImageBuffer::drawConsuming): >+ (WebCore::ImageBuffer::toBGRAData const): Deleted. >+ (WebCore::ImageBuffer::transformColorSpace): Deleted. >+ (WebCore::ImageBuffer::genericConvertToLuminanceMask): Deleted. >+ (WebCore::ImageBuffer::convertToLuminanceMask): Deleted. >+ (WebCore::ImageBuffer::platformLayer const): Deleted. >+ (WebCore::ImageBuffer::copyToPlatformTexture): Deleted. >+ (WebCore::ImageBuffer::memoryCost const): Deleted. >+ (WebCore::ImageBuffer::externalMemoryCost const): Deleted. >+ * platform/graphics/ImageBuffer.h: >+ (WebCore::ImageBuffer::draw): >+ (WebCore::ImageBuffer::drawPattern): >+ (WebCore::ImageBuffer::drawConsuming): >+ (WebCore::ImageBuffer::putImageData): >+ (): Deleted. >+ (WebCore::ImageBuffer::internalSize const): Deleted. >+ (WebCore::ImageBuffer::logicalSize const): Deleted. >+ (WebCore::ImageBuffer::resolutionScale const): Deleted. >+ (WebCore::ImageBuffer::baseTransform const): Deleted. >+ Remove all the back-end and platforms details. Unify the interface such >+ that ImageBuffer does not include preprocessor directives. All the >+ platform specifics will be in ImageBufferBackend. >+ >+ * platform/graphics/ImageBufferBackend.cpp: Added. >+ (WebCore::ImageBufferBackend::ImageBufferBackend): >+ (WebCore::ImageBufferBackend::calculateBackendSize): >+ (WebCore::ImageBufferBackend::sinkIntoNativeImage): >+ (WebCore::ImageBufferBackend::sinkIntoImage): >+ (WebCore::ImageBufferBackend::drawConsuming): >+ (WebCore::ImageBufferBackend::convertToLuminanceMask): >+ (WebCore::ImageBufferBackend::toBGRAData const): >+ (WebCore::copyPremultipliedToPremultiplied): >+ (WebCore::copyPremultipliedToUnpremultiplied): >+ (WebCore::copyUnpremultipliedToPremultiplied): >+ (WebCore::copyFunctor): >+ (WebCore::ImageBufferBackend::copyImagePixels const): >+ (WebCore::ImageBufferBackend::getImageData const): >+ (WebCore::ImageBufferBackend::putImageData): >+ * platform/graphics/ImageBufferBackend.h: Added. >+ (WebCore::ImageBufferBackend::flushContext): >+ (WebCore::ImageBufferBackend::logicalSize const): >+ (WebCore::ImageBufferBackend::backendSize const): >+ (WebCore::ImageBufferBackend::resolutionScale const): >+ (WebCore::ImageBufferBackend::colorSpace const): >+ (WebCore::ImageBufferBackend::baseTransform const): >+ (WebCore::ImageBufferBackend::memoryCost const): >+ (WebCore::ImageBufferBackend::externalMemoryCost const): >+ (WebCore::ImageBufferBackend::transformColorSpace): >+ (WebCore::ImageBufferBackend::platformLayer const): >+ (WebCore::ImageBufferBackend::copyToPlatformTexture const): >+ (WebCore::ImageBufferBackend::bytesPerRow const): >+ (WebCore::ImageBufferBackend::backendColorFormat const): >+ (WebCore::ImageBufferBackend::toBackendCoordinates const): >+ (WebCore::ImageBufferBackend::logicalRect const): >+ (WebCore::ImageBufferBackend::backendRect const): >+ A base class which defines some default behaviors so not all the platforms >+ have to implement them. >+ >+ * platform/graphics/PlatformImageBuffer.h: Added. >+ * platform/graphics/ShadowBlur.cpp: >+ (WebCore::ShadowBlur::drawShadowBuffer): >+ * platform/graphics/cairo/CairoOperations.cpp: >+ (WebCore::Cairo::drawShadowLayerBuffer): >+ (WebCore::Cairo::drawShadowImage): >+ (WebCore::Cairo::fillShadowBuffer): >+ * platform/graphics/cairo/GraphicsContextCairo.cpp: >+ (WebCore::GraphicsContext::clipToImageBuffer): >+ * platform/graphics/cairo/GraphicsContextImplCairo.cpp: >+ (WebCore::GraphicsContextImplCairo::clipToImageBuffer): >+ * platform/graphics/cairo/ImageBufferCairo.cpp: Removed. >+ * platform/graphics/cairo/ImageBufferCairoBackend.cpp: Added. >+ (WebCore::ImageBufferCairoBackend::copyImage const): >+ (WebCore::ImageBufferCairoBackend::draw): >+ (WebCore::ImageBufferCairoBackend::drawPattern): >+ (WebCore::ImageBufferCairoBackend::transformColorSpace): >+ (WebCore::ImageBufferCairoBackend::toDataURL const): >+ (WebCore::ImageBufferCairoBackend::toData const): >+ * platform/graphics/cairo/ImageBufferCairoBackend.h: Added. >+ (WebCore::ImageBufferCairoBackend::platformTransformColorSpace): >+ >+ * platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.cpp: Added. >+ (WebCore::clearSurface): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::create): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::ImageBufferCairoGLSurfaceBackend): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::~ImageBufferCairoGLSurfaceBackend): >+ (WebCore::ImageBuffer::platformLayer const): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::copyToPlatformTexture): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::createCompositorBuffer): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::swapBuffersIfNeeded): >+ (WebCore::ImageBufferCairoGLSurfaceBackend::paintToTextureMapper): >+ * platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.h: Added. >+ An accelerated Cairo back-end. >+ >+ * platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp: Added. >+ (WebCore::ImageBufferCairoImageSurfaceBackend::create): >+ (WebCore::ImageBufferCairoImageSurfaceBackend::ImageBufferCairoImageSurfaceBackend): >+ (WebCore::ImageBufferCairoImageSurfaceBackend::platformTransformColorSpace): >+ * platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h: Added. >+ An unaccelerated Cairo back-end. >+ >+ * platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp: Added. >+ (WebCore::ImageBufferCairoSurfaceBackend::ImageBufferCairoSurfaceBackend): >+ (WebCore::ImageBufferCairoSurfaceBackend::context const): >+ (WebCore::ImageBufferCairoSurfaceBackend::bytesPerRow const): >+ (WebCore::ImageBufferCairoSurfaceBackend::copyNativeImage const): >+ (WebCore::ImageBufferCairoSurfaceBackend::cairoSurfaceCoerceToImage const): >+ (WebCore::ImageBufferCairoSurfaceBackend::toBGRAData const): >+ (WebCore::ImageBufferCairoSurfaceBackend::getImageData const): >+ (WebCore::ImageBufferCairoSurfaceBackend::putImageData): >+ * platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h: Added. >+ * platform/graphics/cg/ImageBufferCG.cpp: Removed. >+ * platform/graphics/cg/ImageBufferCGBackend.cpp: Added. >+ A Cairo surface base class back-end. >+ >+ (WebCore::ImageBufferCGBackend::contextColorSpace): >+ (WebCore::ImageBufferCGBackend::setupContext): >+ (WebCore::createCroppedImageIfNecessary): >+ (WebCore::createBitmapImageAfterScalingIfNeeded): >+ (WebCore::ImageBufferCGBackend::copyImage const): >+ (WebCore::ImageBufferCGBackend::sinkIntoImage): >+ (WebCore::ImageBufferCGBackend::draw): >+ (WebCore::ImageBufferCGBackend::drawPattern): >+ (WebCore::ImageBufferCGBackend::baseTransform const): >+ (WebCore::ImageBufferCGBackend::toCFData const): >+ (WebCore::ImageBufferCGBackend::toData const): >+ (WebCore::ImageBufferCGBackend::toDataURL const): >+ (WebCore::makeVImageBuffer): >+ (WebCore::copyImagePixelsAccelerated): >+ (WebCore::ImageBufferCGBackend::copyImagePixels const): >+ * platform/graphics/cg/ImageBufferCGBackend.h: Added. >+ A base class for all CG back-ends. >+ >+ * platform/graphics/cg/ImageBufferCGBitmapBackend.cpp: Added. >+ (WebCore::ImageBufferCGBitmapBackend::create): >+ (WebCore::ImageBufferCGBitmapBackend::ImageBufferCGBitmapBackend): >+ (WebCore::ImageBufferCGBitmapBackend::context const): >+ (WebCore::ImageBufferCGBitmapBackend::copyNativeImage const): >+ (WebCore::ImageBufferCGBitmapBackend::toBGRAData const): >+ (WebCore::ImageBufferCGBitmapBackend::getImageData const): >+ (WebCore::ImageBufferCGBitmapBackend::putImageData): >+ * platform/graphics/cg/ImageBufferCGBitmapBackend.h: Added. >+ An unaccelerated CG back-end. >+ >+ * platform/graphics/cg/ImageBufferDataCG.cpp: Removed. >+ >+ * platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp: Added. >+ (WebCore::ImageBufferIOSurfaceBackend::calculateBackendSize): >+ (WebCore::ImageBufferIOSurfaceBackend::contextColorSpace): >+ (WebCore::ImageBufferIOSurfaceBackend::create): >+ (WebCore::ImageBufferIOSurfaceBackend::ImageBufferIOSurfaceBackend): >+ (WebCore::ImageBufferIOSurfaceBackend::context const): >+ (WebCore::ImageBufferIOSurfaceBackend::flushContext): >+ (WebCore::ImageBufferIOSurfaceBackend::memoryCost const): >+ (WebCore::ImageBufferIOSurfaceBackend::externalMemoryCost const): >+ (WebCore::ImageBufferIOSurfaceBackend::bytesPerRow const): >+ (WebCore::ImageBufferIOSurfaceBackend::backendColorFormat const): >+ (WebCore::ImageBufferIOSurfaceBackend::copyNativeImage const): >+ (WebCore::ImageBufferIOSurfaceBackend::sinkIntoNativeImage): >+ (WebCore::ImageBufferIOSurfaceBackend::drawConsuming): >+ (WebCore::ImageBufferIOSurfaceBackend::toBGRAData const): >+ (WebCore::ImageBufferIOSurfaceBackend::getImageData const): >+ (WebCore::ImageBufferIOSurfaceBackend::putImageData): >+ * platform/graphics/cg/ImageBufferIOSurfaceBackend.h: Added. >+ An IOSurface accelerated CG back-end. >+ >+ * platform/graphics/cg/PDFDocumentImage.cpp: >+ (WebCore::PDFDocumentImage::updateCachedImageIfNeeded): >+ * platform/graphics/cocoa/IOSurface.mm: >+ (WebCore::IOSurface::createFromImageBuffer): Deleted. >+ * platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp: >+ (WebCore::GraphicsContextGLOpenGL::paintRenderingResultsToCanvas): >+ >+ * platform/graphics/win/ImageBufferDataDirect2D.cpp: Removed. >+ * platform/graphics/win/ImageBufferDataDirect2D.h: Removed. >+ * platform/graphics/win/ImageBufferDirect2D.cpp: Removed. >+ * platform/graphics/win/ImageBufferDirect2DBackend.cpp: Added. >+ (WebCore::ImageBufferDirect2DBackend::create): >+ (WebCore::ImageBufferDirect2DBackend::ImageBufferDirect2DBackend): >+ (WebCore::ImageBufferDirect2DBackend::context const): >+ (WebCore::ImageBufferDirect2DBackend::flushContext): >+ (WebCore::ImageBufferDirect2DBackend::copyNativeImage const): >+ (WebCore::createCroppedImageIfNecessary): >+ (WebCore::createBitmapImageAfterScalingIfNeeded): >+ (WebCore::ImageBufferDirect2DBackend::copyImage const): >+ (WebCore::ImageBufferDirect2DBackend::sinkIntoImage): >+ (WebCore::ImageBufferDirect2DBackend::compatibleBitmap): >+ (WebCore::ImageBufferDirect2DBackend::draw): >+ (WebCore::ImageBufferDirect2DBackend::drawPattern): >+ (WebCore::ImageBufferDirect2DBackend::toDataURL const): >+ (WebCore::ImageBufferDirect2DBackend::toData const): >+ (WebCore::ImageBufferDirect2DBackend::toBGRAData const): >+ (WebCore::ImageBufferDirect2DBackend::getImageData const): >+ (WebCore::ImageBufferDirect2DBackend::putImageData): >+ * platform/graphics/win/ImageBufferDirect2DBackend.h: Added. >+ Remove Direct2D implementation for ImageBuffer. Introduce >+ ImageBufferDirect2DBackend instead. >+ >+ * platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp: >+ (WebCore::WrappedMockRealtimeVideoSource::updateSampleBuffer): >+ * rendering/svg/SVGRenderingContext.cpp: >+ (WebCore::SVGRenderingContext::bufferForeground): >+ >+2020-01-28 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Make ImageBuffer::getImageData() and putImageData() return and take ImageData >+ https://bugs.webkit.org/show_bug.cgi?id=206621 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ -- Combine ImageBuffer::getUnmultipliedImageData() and getPremultipliedImageData() >+ in one function and name it getImageData(); >+ >+ -- Make getImageData() returns an RefPtr<ImageData> since the canvas code >+ used to encapsulate the returned Uint8ClampedArray into an ImageData >+ and send it to JavaScriptCore. >+ >+ -- Rename ImageBuffer::putByteArray() to ImageBuffer::putImageData() and >+ make it take an ImageData since the byte array has to be associated >+ with an IntSize and separating them does not look a good design. >+ >+ -- Remove the enum ImageBuffer::CoordinateSystem. All the callers need to >+ pass rectangles and sizes in logical coordinates. The ImageData has to >+ be scaled according to the ImgeBuffer::resolutionScale(). >+ >+ * bindings/js/SerializedScriptValue.cpp: >+ (WebCore::CloneSerializer::dumpImageBitmap): >+ (WebCore::CloneDeserializer::readImageBitmap): >+ * html/canvas/CanvasRenderingContext2DBase.cpp: >+ (WebCore::CanvasRenderingContext2DBase::getImageData const): >+ (WebCore::CanvasRenderingContext2DBase::putImageData): >+ * html/canvas/CanvasRenderingContext2DBase.h: >+ * page/PageConsoleClient.cpp: >+ (WebCore::PageConsoleClient::screenshot): >+ * platform/graphics/ImageBuffer.cpp: >+ (WebCore::ImageBuffer::convertToLuminanceMask): >+ (WebCore::ImageBuffer::transformColorSpace): Deleted. >+ Move this function to ImageBufferCairo.cpp. >+ >+ (WebCore::ImageBuffer::genericConvertToLuminanceMask): Deleted. >+ convertToLuminanceMask() and genericConvertToLuminanceMask() are not >+ overridden by any platform. So delete genericConvertToLuminanceMask() and >+ move its body to convertToLuminanceMask(). >+ >+ * platform/graphics/ImageBuffer.h: >+ (WebCore::ImageBuffer::draw): >+ (WebCore::ImageBuffer::drawPattern): >+ (WebCore::ImageBuffer::drawConsuming): >+ (WebCore::ImageBuffer::putImageData): >+ Make the private functions be public and remove the friend classes. >+ >+ * platform/graphics/ShadowBlur.cpp: >+ (WebCore::ShadowBlur::blurShadowBuffer): >+ * platform/graphics/cairo/ImageBufferCairo.cpp: >+ (WebCore::ImageBuffer::transformColorSpace): >+ (WebCore::getData): >+ (WebCore::ImageBuffer::getImageData const): >+ (WebCore::ImageBuffer::putImageData): >+ (WebCore::getImageData): Deleted. >+ (WebCore::logicalUnit): Deleted. >+ (WebCore::backingStoreUnit): Deleted. >+ (WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted. >+ (WebCore::ImageBuffer::getPremultipliedImageData const): Deleted. >+ (WebCore::ImageBuffer::putByteArray): Deleted. >+ * platform/graphics/cg/ImageBufferCG.cpp: >+ (WebCore::ImageBuffer::getImageData const): >+ (WebCore::ImageBuffer::putImageData): >+ (WebCore::ImageBuffer::toCFData const): >+ (WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted. >+ (WebCore::ImageBuffer::getPremultipliedImageData const): Deleted. >+ (WebCore::ImageBuffer::putByteArray): Deleted. >+ * platform/graphics/cg/ImageBufferDataCG.cpp: >+ (WebCore::ImageBufferData::getData const): >+ (WebCore::ImageBufferData::putData): >+ * platform/graphics/cg/ImageBufferDataCG.h: >+ All the rectangles and sizes have to be passed in logical coordinates. To >+ deal with the pixels' data we need to scale them by the resolutionScale(). >+ >+ * platform/graphics/cpu/arm/filters/FEBlendNEON.h: >+ (WebCore::FEBlend::platformApplySoftware): >+ * platform/graphics/filters/FEColorMatrix.cpp: >+ (WebCore::FEColorMatrix::platformApplySoftware): >+ * platform/graphics/filters/FEComponentTransfer.cpp: >+ (WebCore::FEComponentTransfer::platformApplySoftware): >+ * platform/graphics/filters/FEComposite.cpp: >+ (WebCore::FEComposite::platformApplySoftware): >+ * platform/graphics/filters/FEConvolveMatrix.cpp: >+ (WebCore::FEConvolveMatrix::platformApplySoftware): >+ * platform/graphics/filters/FEDisplacementMap.cpp: >+ (WebCore::FEDisplacementMap::platformApplySoftware): >+ * platform/graphics/filters/FEDropShadow.cpp: >+ (WebCore::FEDropShadow::platformApplySoftware): >+ This was the only place which was passing a rectangle in a the back-end >+ coordinates along with BackingStoreCoordinateSystem. Instead we can pass >+ the rectangle in logical coordinates and then use ImageData::size() since >+ it must be scaled with resolutionScale() when the ImageData is created. >+ >+ * platform/graphics/filters/FEGaussianBlur.cpp: >+ (WebCore::FEGaussianBlur::platformApplySoftware): >+ * platform/graphics/filters/FELighting.cpp: >+ (WebCore::FELighting::platformApplySoftware): >+ * platform/graphics/filters/FEMorphology.cpp: >+ (WebCore::FEMorphology::platformApplySoftware): >+ * platform/graphics/filters/FETurbulence.cpp: >+ (WebCore::FETurbulence::platformApplySoftware): >+ * platform/graphics/filters/FilterEffect.cpp: >+ (WebCore::FilterEffect::forceValidPreMultipliedPixels): >+ (WebCore::FilterEffect::imageBufferResult): >+ (WebCore::FilterEffect::copyUnmultipliedResult): >+ (WebCore::FilterEffect::copyPremultipliedResult): >+ (WebCore::FilterEffect::createImageBufferResult): >+ (WebCore::FilterEffect::createUnmultipliedImageResult): >+ (WebCore::FilterEffect::createPremultipliedImageResult): >+ * platform/graphics/filters/FilterEffect.h: >+ * platform/graphics/win/ImageBufferDataDirect2D.cpp: >+ (WebCore::ImageBufferData::getData const): >+ (WebCore::ImageBufferData::putData): >+ * platform/graphics/win/ImageBufferDataDirect2D.h: >+ * platform/graphics/win/ImageBufferDirect2D.cpp: >+ (WebCore::ImageBuffer::getImageData const): >+ (WebCore::ImageBuffer::putImageData): >+ (WebCore::ImageBuffer::getUnmultipliedImageData const): Deleted. >+ (WebCore::ImageBuffer::getPremultipliedImageData const): Deleted. >+ (WebCore::ImageBuffer::putByteArray): Deleted. >+ * rendering/shapes/Shape.cpp: >+ (WebCore::Shape::createRasterShape): >+ > 2020-02-03 Sihui Liu <sihui_liu@apple.com> > > Crash in WebCore::IDBServer::IDBServer::createIndex >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index f8c8c33a7d34fa3bfbfde1f39cd87c19c5bcdcea..2dbd1316ae142975e6391f3b898de831df182458 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,151 @@ >+2020-02-04 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Implement the remote ImageBuffer >+ https://bugs.webkit.org/show_bug.cgi?id=207221 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ RemoteImageBuffer and RemoteImageBufferProxy will be responsible for >+ handling the communications of the ImageBuffer parts between WebProcess >+ and GPUProcess. >+ >+ * DerivedSources-input.xcfilelist: >+ * DerivedSources-output.xcfilelist: >+ * DerivedSources.make: >+ * GPUProcess/RenderingBackend/RemoteImageBufferProxy.cpp: Added. >+ (WebKit::RemoteImageBufferProxy::RemoteImageBufferProxy): >+ (WebKit::RemoteImageBufferProxy::~RemoteImageBufferProxy): >+ (WebKit::RemoteImageBufferProxy::messageSenderConnection const): >+ (WebKit::RemoteImageBufferProxy::messageSenderDestinationID const): >+ * GPUProcess/RenderingBackend/RemoteImageBufferProxy.h: Added. >+ * GPUProcess/RenderingBackend/RemoteImageBufferProxy.messages.in: Added. >+ * Sources.txt: >+ * SourcesCocoa.txt: >+ * WebKit.xcodeproj/project.pbxproj: >+ * WebProcess/GPU/RenderingBackend/RemoteImageBuffer.cpp: Added. >+ (WebKit::RemoteImageBuffer::RemoteImageBuffer): >+ (WebKit::RemoteImageBuffer::~RemoteImageBuffer): >+ (WebKit::RemoteImageBuffer::messageSenderConnection const): >+ (WebKit::RemoteImageBuffer::messageSenderDestinationID const): >+ * WebProcess/GPU/RenderingBackend/RemoteImageBuffer.h: Added. >+ * WebProcess/GPU/RenderingBackend/RemoteImageBuffer.messages.in: Added. >+ >+2020-02-04 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Implement the remote RenderingBackend >+ https://bugs.webkit.org/show_bug.cgi?id=207198 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ -- RemoteRenderingBackend will be created by WebChromeClient and owned by >+ Chrome. ImageBuffer::create will have access to it through the HostWindow >+ argument. All types of ImageBuffer will be created by >+ RemoteRenderingBackend::createImageBuffer() method. In-process ImageBuffer >+ types will be created by RenderingBackend:: createImageBuffer(). >+ >+ -- RemoteRenderingBackendProxy will be created and owned by >+ GPUConnectionToWebProcess. >+ >+ * DerivedSources-input.xcfilelist: >+ * DerivedSources-output.xcfilelist: >+ * DerivedSources.make: >+ >+ * GPUProcess/GPUConnectionToWebProcess.cpp: >+ (WebKit::GPUConnectionToWebProcess::createRenderingBackend): >+ (WebKit::GPUConnectionToWebProcess::releaseRenderingBackend): >+ Add methods for creating and releasing RemoteRenderingBackendProxy. >+ >+ (WebKit::GPUConnectionToWebProcess::dispatchMessage): >+ (WebKit::GPUConnectionToWebProcess::dispatchSyncMessage): >+ (WebKit::GPUConnectionToWebProcess::didReceiveMessage): Deleted. >+ (WebKit::GPUConnectionToWebProcess::didReceiveSyncMessage): Deleted. >+ * GPUProcess/GPUConnectionToWebProcess.h: >+ (WebKit::GPUConnectionToWebProcess::messageReceiverMap): >+ Add a MessageReceiverMap to GPUConnectionToWebProcess so messages can be >+ dispatched to its MessageReceivers. >+ >+ * GPUProcess/GPUConnectionToWebProcess.messages.in: >+ Add the attribute 'WantsDispatchMessage'. >+ Add messages for creating and releasing RemoteRenderingBackendProxy. >+ >+ * GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.cpp: Added. >+ (WebKit::RemoteRenderingBackendProxy::create): >+ (WebKit::RemoteRenderingBackendProxy::RemoteRenderingBackendProxy): >+ (WebKit::RemoteRenderingBackendProxy::~RemoteRenderingBackendProxy): >+ (WebKit::RemoteRenderingBackendProxy::messageSenderConnection const): >+ (WebKit::RemoteRenderingBackendProxy::messageSenderDestinationID const): >+ >+ (WebKit::RemoteRenderingBackendProxy::createImageBuffer): >+ (WebKit::RemoteRenderingBackendProxy::releaseImageBuffer): >+ Add methods for creating and releasing remote ImageBuffer proxy. >+ >+ * GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.h: Added. >+ (WebKit::RemoteRenderingBackendProxy::renderingBackendIdentifier const): >+ * GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.messages.in: Added. >+ Add messages for creating and releasing remote ImageBuffer proxy. >+ >+ * GPUProcess/webrtc/RemoteSampleBufferDisplayLayer.h: >+ * GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp: >+ * GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h: >+ >+ * Scripts/webkit/messages.py: >+ If the attribute WantsDispatchMessage is added to the messages.in file, >+ a call to 'dispatchMessage()' will be added to didReceiveMessage() and >+ a call to 'dispatchSyncMessage()' will be added to dispatchSyncMessage() >+ even if no messages are defined in messages.in. >+ >+ * Shared/WebCoreArgumentCoders.h: >+ Add encoding and decoding support for AlphaPremultiplication and RenderingMode. >+ >+ * Sources.txt: >+ * SourcesCocoa.txt: >+ * WebKit.xcodeproj/project.pbxproj: >+ >+ * WebProcess/GPU/GPUProcessConnection.cpp: >+ (WebKit::GPUProcessConnection::dispatchMessage): >+ (WebKit::GPUProcessConnection::dispatchSyncMessage): >+ (WebKit::GPUProcessConnection::didReceiveInvalidMessage): >+ (WebKit::GPUProcessConnection::didReceiveMessage): Deleted. >+ * WebProcess/GPU/GPUProcessConnection.h: >+ (WebKit::GPUProcessConnection::messageReceiverMap): >+ Add a MessageReceiverMap to GPUProcessConnection so messages can be >+ dispatched to its MessageReceivers. >+ >+ * WebProcess/GPU/GPUProcessConnection.messages.in: >+ Add the attribute 'WantsDispatchMessage'. >+ >+ * WebProcess/GPU/RenderingBackend/ImageBufferIdentifier.h: Added. >+ Add an ObjectIdentifier for remote ImageBuffer. >+ >+ * WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.cpp: Added. >+ (WebKit::RemoteRenderingBackend::create): >+ (WebKit::RemoteRenderingBackend::RemoteRenderingBackend): >+ (WebKit::RemoteRenderingBackend::~RemoteRenderingBackend): >+ (WebKit::RemoteRenderingBackend::messageSenderConnection const): >+ (WebKit::RemoteRenderingBackend::messageSenderDestinationID const): >+ >+ (WebKit::RemoteRenderingBackend::createImageBuffer): >+ Creates all types of ImageBuffer. For now it only creates the in process >+ RenderingBackend. >+ >+ * WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.h: Added. >+ * WebProcess/GPU/RenderingBackend/RenderingBackendIdentifier.h: Added. >+ >+ * WebProcess/WebCoreSupport/WebChromeClient.cpp: >+ (WebKit::WebChromeClient::createRenderingBackend const): >+ * WebProcess/WebCoreSupport/WebChromeClient.h: >+ Create RemoteRenderingBackend which will be owned by the Chrome. >+ >+2020-02-03 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Allow different back-ends for ImageBuffer >+ https://bugs.webkit.org/show_bug.cgi?id=207048 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebProcess/WebPage/WebFrame.cpp: >+ (WebKit::WebFrame::createSelectionSnapshot const): >+ > 2020-02-03 Chris Dumez <cdumez@apple.com> > > [WK2] Use per-UIProcess default cookie storage for Mac Catalyst apps >diff --git a/Source/WebCore/Headers.cmake b/Source/WebCore/Headers.cmake >index 52b36410989658d49fc25069d20830945f068d2b..4861f28fdb06fbfbf0c96123de20c3141d1c9f50 100644 >--- a/Source/WebCore/Headers.cmake >+++ b/Source/WebCore/Headers.cmake >@@ -1043,6 +1043,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/graphics/ColorHash.h > platform/graphics/ColorSpace.h > platform/graphics/ComplexTextController.h >+ platform/graphics/ContextualImageBuffer.h > platform/graphics/DashArray.h > platform/graphics/DecodingOptions.h > platform/graphics/DisplayRefreshMonitor.h >@@ -1094,7 +1095,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/graphics/Image.h > platform/graphics/ImageBackingStore.h > platform/graphics/ImageBuffer.h >- platform/graphics/ImageBufferData.h >+ platform/graphics/ImageBufferBackend.h > platform/graphics/ImageFrame.h > platform/graphics/ImageObserver.h > platform/graphics/ImageOrientation.h >@@ -1127,12 +1128,14 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/graphics/PathUtilities.h > platform/graphics/Pattern.h > platform/graphics/PlatformDisplay.h >+ platform/graphics/PlatformImageBuffer.h > platform/graphics/PlatformLayer.h > platform/graphics/PlatformMediaResourceLoader.h > platform/graphics/PlatformTextTrack.h > platform/graphics/PlatformTimeRanges.h > platform/graphics/Region.h > platform/graphics/RemoteVideoSample.h >+ platform/graphics/RenderingBackend.h > platform/graphics/RenderingMode.h > platform/graphics/RoundedRect.h > platform/graphics/StringTruncator.h >diff --git a/Source/WebCore/PlatformAppleWin.cmake b/Source/WebCore/PlatformAppleWin.cmake >index f712927cc918f3ab0fe708a8ac017bd0f3cf940d..5d17743ed3843011fa86ce511be92933099292e5 100644 >--- a/Source/WebCore/PlatformAppleWin.cmake >+++ b/Source/WebCore/PlatformAppleWin.cmake >@@ -83,8 +83,7 @@ if (${USE_DIRECT2D}) > platform/graphics/win/GradientDirect2D.cpp > platform/graphics/win/GraphicsContextDirect2D.cpp > platform/graphics/win/GraphicsLayerDirect2D.cpp >- platform/graphics/win/ImageBufferDataDirect2D.cpp >- platform/graphics/win/ImageBufferDirect2D.cpp >+ platform/graphics/win/ImageBufferDirect2DBackend.cpp > platform/graphics/win/ImageDecoderDirect2D.cpp > platform/graphics/win/ImageDirect2D.cpp > platform/graphics/win/NativeImageDirect2D.cpp >@@ -132,8 +131,9 @@ else () > platform/graphics/cg/GraphicsContextGLCG.cpp > platform/graphics/cg/GraphicsContextCG.cpp > platform/graphics/cg/IOSurfacePool.cpp >- platform/graphics/cg/ImageBufferCG.cpp >- platform/graphics/cg/ImageBufferDataCG.cpp >+ platform/graphics/cg/ImageBufferCGBackend.cpp >+ platform/graphics/cg/ImageBufferCGBitmapBackend.cpp >+ platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp > platform/graphics/cg/ImageBufferUtilitiesCG.cpp > platform/graphics/cg/ImageDecoderCG.cpp > platform/graphics/cg/ImageSourceCGWin.cpp >@@ -176,7 +176,9 @@ else () > > platform/graphics/cg/GraphicsContextCG.h > platform/graphics/cg/IOSurfacePool.h >- platform/graphics/cg/ImageBufferDataCG.h >+ platform/graphics/cg/ImageBufferCGBackend.h >+ platform/graphics/cg/ImageBufferCGBitmapBackend.h >+ platform/graphics/cg/ImageBufferIOSurfaceBackend.h > platform/graphics/cg/ImageBufferUtilitiesCG.h > platform/graphics/cg/PDFDocumentImage.h > platform/graphics/cg/UTIRegistry.h >diff --git a/Source/WebCore/PlatformFTW.cmake b/Source/WebCore/PlatformFTW.cmake >index 9ab468739ef11ff609b9629288bb01b16da702aa..f4b9b7f8866b1241a85579b2e61f7bae543d875a 100644 >--- a/Source/WebCore/PlatformFTW.cmake >+++ b/Source/WebCore/PlatformFTW.cmake >@@ -84,8 +84,7 @@ list(APPEND WebCore_SOURCES > platform/graphics/win/GraphicsContextImplDirect2D.cpp > platform/graphics/win/GraphicsContextWin.cpp > platform/graphics/win/IconWin.cpp >- platform/graphics/win/ImageBufferDataDirect2D.cpp >- platform/graphics/win/ImageBufferDirect2D.cpp >+ platform/graphics/win/ImageBufferDirect2DBackend.cpp > platform/graphics/win/ImageDecoderDirect2D.cpp > platform/graphics/win/ImageDirect2D.cpp > platform/graphics/win/ImageWin.cpp >@@ -201,7 +200,6 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/graphics/win/FullScreenController.h > platform/graphics/win/FullScreenControllerClient.h > platform/graphics/win/GraphicsContextImplDirect2D.h >- platform/graphics/win/ImageBufferDataDirect2D.h > platform/graphics/win/ImageDecoderDirect2D.h > platform/graphics/win/LocalWindowsContext.h > platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h >diff --git a/Source/WebCore/PlatformMac.cmake b/Source/WebCore/PlatformMac.cmake >index aec32067d3e6f2f49d193e0b1a66bb09591160c8..12215ab1d10fbdd8aeca267f708463735bf5fed3 100644 >--- a/Source/WebCore/PlatformMac.cmake >+++ b/Source/WebCore/PlatformMac.cmake >@@ -291,8 +291,10 @@ list(APPEND WebCore_SOURCES > platform/graphics/cg/GraphicsContextGLCG.cpp > platform/graphics/cg/GraphicsContextCG.cpp > platform/graphics/cg/IOSurfacePool.cpp >- platform/graphics/cg/ImageBufferCG.cpp >- platform/graphics/cg/ImageBufferDataCG.cpp >+ platform/graphics/cg/ImageBufferCGBackend.cpp >+ platform/graphics/cg/ImageBufferCGBitmapBackend.cpp >+ platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp >+ platform/graphics/cg/ImageBufferUtilitiesCG.cpp > platform/graphics/cg/ImageDecoderCG.cpp > platform/graphics/cg/ImageSourceCGMac.mm > platform/graphics/cg/IntPointCG.cpp >@@ -527,7 +529,9 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS > > platform/graphics/cg/GraphicsContextCG.h > platform/graphics/cg/IOSurfacePool.h >- platform/graphics/cg/ImageBufferDataCG.h >+ platform/graphics/cg/ImageBufferCGBackend.h >+ platform/graphics/cg/ImageBufferCGBitmapBackend.h >+ platform/graphics/cg/ImageBufferIOSurfaceBackend.h > platform/graphics/cg/ImageBufferUtilitiesCG.h > platform/graphics/cg/PDFDocumentImage.h > platform/graphics/cg/UTIRegistry.h >diff --git a/Source/WebCore/PlatformWin.cmake b/Source/WebCore/PlatformWin.cmake >index 4f307159b7ed806eb81952bba45f5c07a8dc93eb..8af701c777fe152e2316ca500043ad971acbf1ad 100644 >--- a/Source/WebCore/PlatformWin.cmake >+++ b/Source/WebCore/PlatformWin.cmake >@@ -119,7 +119,6 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/graphics/win/DIBPixelData.h > platform/graphics/win/FullScreenController.h > platform/graphics/win/FullScreenControllerClient.h >- platform/graphics/win/ImageBufferDataDirect2D.h > platform/graphics/win/LocalWindowsContext.h > platform/graphics/win/MediaPlayerPrivateFullscreenWindow.h > platform/graphics/win/SharedGDIObject.h >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index 116b388d2d5fd5cd2fd9a4e6250c386b45c71265..3a35d6c1314e5006ee57996f4b835f9820be206a 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -1864,6 +1864,7 @@ platform/graphics/HEVCUtilities.cpp > platform/graphics/Icon.cpp > platform/graphics/Image.cpp > platform/graphics/ImageBuffer.cpp >+platform/graphics/ImageBufferBackend.cpp > platform/graphics/ImageDecoder.cpp > platform/graphics/ImageFrame.cpp > platform/graphics/ImageSource.cpp >@@ -1883,6 +1884,7 @@ platform/graphics/Pattern.cpp > platform/graphics/PlatformTimeRanges.cpp > platform/graphics/Region.cpp > platform/graphics/RemoteVideoSample.cpp >+platform/graphics/RenderingBackend.cpp > platform/graphics/RoundedRect.cpp > platform/graphics/ShadowBlur.cpp > platform/graphics/StringTruncator.cpp >diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt >index 4de75df8df0b8f90e5b258157eada4a69d3b5916..7661e2b9ad2b3918a53b167e47bc1453ae6fc91c 100644 >--- a/Source/WebCore/SourcesCocoa.txt >+++ b/Source/WebCore/SourcesCocoa.txt >@@ -291,8 +291,9 @@ platform/graphics/cg/GradientCG.cpp > platform/graphics/cg/GraphicsContextGLCG.cpp > platform/graphics/cg/GraphicsContextCG.cpp > platform/graphics/cg/IOSurfacePool.cpp >-platform/graphics/cg/ImageBufferCG.cpp >-platform/graphics/cg/ImageBufferDataCG.cpp >+platform/graphics/cg/ImageBufferCGBackend.cpp >+platform/graphics/cg/ImageBufferCGBitmapBackend.cpp >+platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp > platform/graphics/cg/ImageBufferUtilitiesCG.cpp > platform/graphics/cg/ImageDecoderCG.cpp > platform/graphics/cg/ImageSourceCGMac.mm >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index af04412418e6dbb0f0b3b17a6d9a8ca6ba8116b4..9278ca825f443130f65e409d9a8dccf0f4931dc7 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -645,8 +645,6 @@ > 20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 20D629251253690B00081543 /* InspectorInstrumentation.h */; }; > 225A16B50D5C11E900090295 /* WebEventRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 225A16B30D5C11E900090295 /* WebEventRegion.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 228C284510D82500009D0D0E /* ScriptWrappable.h in Headers */ = {isa = PBXBuildFile; fileRef = 228C284410D82500009D0D0E /* ScriptWrappable.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 22BD9F7F1353625C009BD102 /* ImageBufferData.h in Headers */ = {isa = PBXBuildFile; fileRef = 22BD9F7D1353625C009BD102 /* ImageBufferData.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 22BD9F81135364FE009BD102 /* ImageBufferDataCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 22BD9F80135364FE009BD102 /* ImageBufferDataCG.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 24D9129213CA951E00D21915 /* JSSVGAltGlyphDefElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 24D9129013CA951E00D21915 /* JSSVGAltGlyphDefElement.h */; }; > 24D9129613CA956100D21915 /* JSSVGAltGlyphItemElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 24D9129413CA956100D21915 /* JSSVGAltGlyphItemElement.h */; }; > 24D9129A13CA971400D21915 /* JSSVGGlyphRefElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 24D9129913CA971400D21915 /* JSSVGGlyphRefElement.h */; }; >@@ -833,17 +831,17 @@ > 2DACB9E923755D0000B4C185 /* GraphicsContextImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F00123F1FAD87D600531D76 /* GraphicsContextImpl.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 2DAF343D1EA7E0F100382CD3 /* ConstantPropertyMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DAF343B1EA7E0F100382CD3 /* ConstantPropertyMap.h */; }; > 2DD5A7271EBEE47D009BA597 /* CompositionUnderline.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DD5A7261EBEE47D009BA597 /* CompositionUnderline.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 2DDE1CE31F574AE500D1A365 /* JSVRFieldOfView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CE01F574AD100D1A365 /* JSVRFieldOfView.h */; }; >- 2DDE1CE41F574AE900D1A365 /* JSVRDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CDE1F574AAB00D1A365 /* JSVRDisplay.h */; }; >- 2DDE1CF81F574C3900D1A365 /* JSVRDisplayCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CE61F574BFF00D1A365 /* JSVRDisplayCapabilities.h */; }; >- 2DDE1CFA1F574C3E00D1A365 /* JSVRDisplayEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CE81F574BFF00D1A365 /* JSVRDisplayEvent.h */; }; >- 2DDE1CFC1F574CEE00D1A365 /* JSVRDisplayEventReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CEA1F574BFF00D1A365 /* JSVRDisplayEventReason.h */; }; >- 2DDE1CFE1F574CF300D1A365 /* JSVREye.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CEC1F574BFF00D1A365 /* JSVREye.h */; }; >- 2DDE1D001F574CF700D1A365 /* JSVREyeParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CEE1F574BFF00D1A365 /* JSVREyeParameters.h */; }; >- 2DDE1D021F574D0000D1A365 /* JSVRFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CF01F574BFF00D1A365 /* JSVRFrameData.h */; }; >- 2DDE1D041F574D0500D1A365 /* JSVRLayerInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CF21F574BFF00D1A365 /* JSVRLayerInit.h */; }; >- 2DDE1D061F574D0A00D1A365 /* JSVRPose.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CF41F574BFF00D1A365 /* JSVRPose.h */; }; >- 2DDE1D081F574D0E00D1A365 /* JSVRStageParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDE1CF61F574BFF00D1A365 /* JSVRStageParameters.h */; }; >+ 2DDE1CE31F574AE500D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1CE41F574AE900D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1CF81F574C3900D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1CFA1F574C3E00D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1CFC1F574CEE00D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1CFE1F574CF300D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1D001F574CF700D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1D021F574D0000D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1D041F574D0500D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1D061F574D0A00D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; >+ 2DDE1D081F574D0E00D1A365 /* (null) in Headers */ = {isa = PBXBuildFile; }; > 2DE70023192FE82A00B0975C /* DisplayRefreshMonitorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE70022192FE82A00B0975C /* DisplayRefreshMonitorMac.h */; }; > 2DF512CE1D873E47001D6780 /* ReplaceRangeWithTextCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DF512CC1D873E47001D6780 /* ReplaceRangeWithTextCommand.h */; }; > 2DFA488F1DB541D000362B99 /* BufferSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DFA488E1DB541C200362B99 /* BufferSource.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -2145,11 +2143,13 @@ > 72144334223EC91600F12FF7 /* SVGPropertyOwner.h in Headers */ = {isa = PBXBuildFile; fileRef = 55EE5360223B2A2100FBA944 /* SVGPropertyOwner.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 72283F0E230B268C00F5D828 /* ImagePaintingOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 72C18A3F230B04B7006847C7 /* ImagePaintingOptions.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 722A815D238FDAF000C00583 /* AnimationFrameRate.h in Headers */ = {isa = PBXBuildFile; fileRef = 722A815C238FD50500C00583 /* AnimationFrameRate.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 7239406523E8828600E3B545 /* RenderingBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 7239406423E87D5400E3B545 /* RenderingBackend.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 724ED3321A3A8B2300F5F13C /* JSEXTBlendMinMax.h in Headers */ = {isa = PBXBuildFile; fileRef = 724ED3301A3A8B2300F5F13C /* JSEXTBlendMinMax.h */; }; > 724EE5501DC80D7F00A91FFB /* ActivityState.h in Headers */ = {isa = PBXBuildFile; fileRef = 724EE54E1DC7F25B00A91FFB /* ActivityState.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 724EE5511DC80D8400A91FFB /* ActivityStateChangeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 724EE54F1DC7F25B00A91FFB /* ActivityStateChangeObserver.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 7299BC6723D6A53200CC6883 /* AlphaPremultiplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6423D686A600CC6883 /* AlphaPremultiplication.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 7299BC6823D6A53E00CC6883 /* RenderingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 7299BC6623D686C600CC6883 /* RenderingMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 72BAC3A523E17328008D741C /* ImageBufferBackend.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 7553CFE8108F473F00EA281E /* TimelineRecordFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7553CFE6108F473F00EA281E /* TimelineRecordFactory.h */; }; > 75793E840D0CE0B3007FC0AC /* MessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 75793E810D0CE0B3007FC0AC /* MessageEvent.h */; }; > 75793EC90D0CE72D007FC0AC /* JSMessageEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 75793EC70D0CE72D007FC0AC /* JSMessageEvent.h */; }; >@@ -2580,7 +2580,6 @@ > 8AF4E55C11DC5A63000ED3DE /* PerformanceTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AF4E55911DC5A63000ED3DE /* PerformanceTiming.h */; }; > 8BD37A68201BB39C0011734A /* ReadableStreamChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BD37A67201BB39C0011734A /* ReadableStreamChunk.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 8E4C96DD1AD4483500365A50 /* JSFetchResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E4C96D91AD4483500365A50 /* JSFetchResponse.h */; }; >- 8E620E8120EE6024007BC5EF /* VRPlatformDisplayClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E620E8020EE5FFC007BC5EF /* VRPlatformDisplayClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 8EC6C963201A251600FBFA53 /* GapLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC6C961201A250100FBFA53 /* GapLength.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 8F67561B1288B17B0047ACA3 /* EventQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F6756191288B17B0047ACA3 /* EventQueue.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 9001774112E0347800648462 /* OESStandardDerivatives.h in Headers */ = {isa = PBXBuildFile; fileRef = 9001773E12E0347800648462 /* OESStandardDerivatives.h */; }; >@@ -6559,9 +6558,6 @@ > 225A16B30D5C11E900090295 /* WebEventRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebEventRegion.h; sourceTree = "<group>"; }; > 225A16B40D5C11E900090295 /* WebEventRegion.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebEventRegion.mm; sourceTree = "<group>"; }; > 228C284410D82500009D0D0E /* ScriptWrappable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptWrappable.h; sourceTree = "<group>"; }; >- 2292B27B1356669400CF11EF /* ImageBufferDataCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferDataCG.cpp; sourceTree = "<group>"; }; >- 22BD9F7D1353625C009BD102 /* ImageBufferData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferData.h; sourceTree = "<group>"; }; >- 22BD9F80135364FE009BD102 /* ImageBufferDataCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferDataCG.h; sourceTree = "<group>"; }; > 2442BBF81194C9D300D49469 /* HashChangeEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashChangeEvent.h; sourceTree = "<group>"; }; > 24D9128F13CA951E00D21915 /* JSSVGAltGlyphDefElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGAltGlyphDefElement.cpp; sourceTree = "<group>"; }; > 24D9129013CA951E00D21915 /* JSSVGAltGlyphDefElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSVGAltGlyphDefElement.h; sourceTree = "<group>"; }; >@@ -9580,6 +9576,10 @@ > 721443452240C8BA00F12FF7 /* SVGAnimatedValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedValueProperty.h; sourceTree = "<group>"; }; > 721443462240CAD200F12FF7 /* SVGValueProperty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGValueProperty.h; sourceTree = "<group>"; }; > 722A815C238FD50500C00583 /* AnimationFrameRate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnimationFrameRate.h; sourceTree = "<group>"; }; >+ 7239405E23E5F53F00E3B545 /* DisplayListImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayListImageBuffer.h; sourceTree = "<group>"; }; >+ 7239406023E5F56700E3B545 /* DisplayListDrawingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayListDrawingContext.h; sourceTree = "<group>"; }; >+ 7239406223E87D5300E3B545 /* RenderingBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderingBackend.cpp; sourceTree = "<group>"; }; >+ 7239406423E87D5400E3B545 /* RenderingBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderingBackend.h; sourceTree = "<group>"; }; > 724ED3291A3A7E5400F5F13C /* EXTBlendMinMax.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXTBlendMinMax.cpp; sourceTree = "<group>"; }; > 724ED32A1A3A7E5400F5F13C /* EXTBlendMinMax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTBlendMinMax.h; sourceTree = "<group>"; }; > 724ED32B1A3A7E5400F5F13C /* EXTBlendMinMax.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTBlendMinMax.idl; sourceTree = "<group>"; }; >@@ -9602,6 +9602,16 @@ > 727AFED31A2EA6A0000442E8 /* EXTsRGB.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EXTsRGB.idl; sourceTree = "<group>"; }; > 7299BC6423D686A600CC6883 /* AlphaPremultiplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AlphaPremultiplication.h; sourceTree = "<group>"; }; > 7299BC6623D686C600CC6883 /* RenderingMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderingMode.h; sourceTree = "<group>"; }; >+ 72BAC3A423E17327008D741C /* ImageBufferBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferBackend.cpp; sourceTree = "<group>"; }; >+ 72BAC3A523E17328008D741C /* ImageBufferBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferBackend.h; sourceTree = "<group>"; }; >+ 72BAC3A623E17328008D741C /* PlatformImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformImageBuffer.h; sourceTree = "<group>"; }; >+ 72BAC3A723E17328008D741C /* ContextualImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextualImageBuffer.h; sourceTree = "<group>"; }; >+ 72BAC3A823E1E543008D741C /* ImageBufferCGBitmapBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferCGBitmapBackend.cpp; sourceTree = "<group>"; }; >+ 72BAC3A923E1E543008D741C /* ImageBufferIOSurfaceBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferIOSurfaceBackend.cpp; sourceTree = "<group>"; }; >+ 72BAC3AA23E1E544008D741C /* ImageBufferCGBitmapBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferCGBitmapBackend.h; sourceTree = "<group>"; }; >+ 72BAC3AB23E1E544008D741C /* ImageBufferIOSurfaceBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferIOSurfaceBackend.h; sourceTree = "<group>"; }; >+ 72BAC3AC23E1E545008D741C /* ImageBufferCGBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferCGBackend.cpp; sourceTree = "<group>"; }; >+ 72BAC3AD23E1E545008D741C /* ImageBufferCGBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferCGBackend.h; sourceTree = "<group>"; }; > 72C18A3F230B04B7006847C7 /* ImagePaintingOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagePaintingOptions.h; sourceTree = "<group>"; }; > 72E417611A2E8D2F004C562A /* JSEXTsRGB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEXTsRGB.cpp; sourceTree = "<group>"; }; > 72E417621A2E8D2F004C562A /* JSEXTsRGB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEXTsRGB.h; sourceTree = "<group>"; }; >@@ -10544,8 +10554,6 @@ > 8E33CD93201A29C100E39093 /* GapLength.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GapLength.cpp; sourceTree = "<group>"; }; > 8E4C96D81AD4483500365A50 /* JSFetchResponse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchResponse.cpp; sourceTree = "<group>"; }; > 8E4C96D91AD4483500365A50 /* JSFetchResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFetchResponse.h; sourceTree = "<group>"; }; >- 8E620E7E20EE5FE2007BC5EF /* VRPlatformDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VRPlatformDisplay.cpp; sourceTree = "<group>"; }; >- 8E620E8020EE5FFC007BC5EF /* VRPlatformDisplayClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VRPlatformDisplayClient.h; sourceTree = "<group>"; }; > 8EC6C961201A250100FBFA53 /* GapLength.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GapLength.h; sourceTree = "<group>"; }; > 8F6756191288B17B0047ACA3 /* EventQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventQueue.h; sourceTree = "<group>"; }; > 8F934D831189F1EE00508D5D /* JSExecState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSExecState.h; sourceTree = "<group>"; }; >@@ -12675,7 +12683,6 @@ > B2A015940AF6CD53006BCE0E /* GraphicsTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsTypes.cpp; sourceTree = "<group>"; }; > B2A015950AF6CD53006BCE0E /* GraphicsTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GraphicsTypes.h; sourceTree = "<group>"; }; > B2A10B910B3818BD00099AA4 /* ImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageBuffer.h; sourceTree = "<group>"; }; >- B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferCG.cpp; sourceTree = "<group>"; }; > B2A1F2A10CEF0ABF00442F6A /* SVGFontElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFontElement.cpp; sourceTree = "<group>"; }; > B2A1F2A20CEF0ABF00442F6A /* SVGFontElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGFontElement.h; sourceTree = "<group>"; }; > B2A1F2A30CEF0ABF00442F6A /* SVGFontElement.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGFontElement.idl; sourceTree = "<group>"; }; >@@ -16689,6 +16696,7 @@ > children = ( > 0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */, > 0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */, >+ 7239406023E5F56700E3B545 /* DisplayListDrawingContext.h */, > 0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */, > 0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */, > 0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */, >@@ -24840,9 +24848,12 @@ > 934907E3125BBBC8007F23A0 /* GraphicsContextCG.h */, > 6E21C6C11126339900A7BE02 /* GraphicsContextGLCG.cpp */, > A80D67070E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h */, >- B2A10B930B3818D700099AA4 /* ImageBufferCG.cpp */, >- 2292B27B1356669400CF11EF /* ImageBufferDataCG.cpp */, >- 22BD9F80135364FE009BD102 /* ImageBufferDataCG.h */, >+ 72BAC3AC23E1E545008D741C /* ImageBufferCGBackend.cpp */, >+ 72BAC3AD23E1E545008D741C /* ImageBufferCGBackend.h */, >+ 72BAC3A823E1E543008D741C /* ImageBufferCGBitmapBackend.cpp */, >+ 72BAC3AA23E1E544008D741C /* ImageBufferCGBitmapBackend.h */, >+ 72BAC3A923E1E543008D741C /* ImageBufferIOSurfaceBackend.cpp */, >+ 72BAC3AB23E1E544008D741C /* ImageBufferIOSurfaceBackend.h */, > CD58949321874064004F424A /* ImageBufferUtilitiesCG.cpp */, > CD3E21DB21833F5100E66F55 /* ImageBufferUtilitiesCG.h */, > 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */, >@@ -24934,12 +24945,14 @@ > 0FE6C76C1FBFB7A60025C053 /* ColorUtilities.h */, > C2F4E7881E45AEDF006D7105 /* ComplexTextController.cpp */, > C2F4E7891E45AEDF006D7105 /* ComplexTextController.h */, >+ 72BAC3A723E17328008D741C /* ContextualImageBuffer.h */, > 2D2FC0541460CD6F00263633 /* CrossfadeGeneratedImage.cpp */, > 2D2FC0551460CD6F00263633 /* CrossfadeGeneratedImage.h */, > 4B7AE4952177B63E00C59959 /* CustomPaintImage.cpp */, > 4B7AE4922177B56F00C59959 /* CustomPaintImage.h */, > A8CB41020E85B8A50032C4F0 /* DashArray.h */, > 555130001E7CCCCA00A69E38 /* DecodingOptions.h */, >+ 7239405E23E5F53F00E3B545 /* DisplayListImageBuffer.h */, > 49FC7A4F1444AF5F00A5D864 /* DisplayRefreshMonitor.cpp */, > 49AF2D6814435D050016A784 /* DisplayRefreshMonitor.h */, > 2D29ECC1192ECC8300984B78 /* DisplayRefreshMonitorClient.cpp */, >@@ -25031,7 +25044,8 @@ > 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */, > 43D2597613C816F400608559 /* ImageBuffer.cpp */, > B2A10B910B3818BD00099AA4 /* ImageBuffer.h */, >- 22BD9F7D1353625C009BD102 /* ImageBufferData.h */, >+ 72BAC3A423E17327008D741C /* ImageBufferBackend.cpp */, >+ 72BAC3A523E17328008D741C /* ImageBufferBackend.h */, > CD19FEA71F573972000C42FB /* ImageDecoder.cpp */, > CD19FEA61F573972000C42FB /* ImageDecoder.h */, > 5576A5621D88A70800CCC04C /* ImageFrame.cpp */, >@@ -25088,6 +25102,7 @@ > 2D5002FA1B56D7990020AAF7 /* PathUtilities.h */, > A8FA6E5C0E4CFDED00D5CF49 /* Pattern.cpp */, > A8FA6E5B0E4CFDED00D5CF49 /* Pattern.h */, >+ 72BAC3A623E17328008D741C /* PlatformImageBuffer.h */, > 0562F9601573F88F0031CA16 /* PlatformLayer.h */, > CEEFCD7B19DB33DC003876D7 /* PlatformMediaResourceLoader.h */, > 072847E216EBC5B00043CFA4 /* PlatformTextTrack.h */, >@@ -25097,6 +25112,8 @@ > BCAB418013E356E800D8AAF3 /* Region.h */, > 073A15512177A39800EA08F2 /* RemoteVideoSample.cpp */, > 073A15532177A39A00EA08F2 /* RemoteVideoSample.h */, >+ 7239406223E87D5300E3B545 /* RenderingBackend.cpp */, >+ 7239406423E87D5400E3B545 /* RenderingBackend.h */, > 7299BC6623D686C600CC6883 /* RenderingMode.h */, > A73F95FC12C97BFE0031AAF9 /* RoundedRect.cpp */, > A73F95FD12C97BFE0031AAF9 /* RoundedRect.h */, >@@ -25823,7 +25840,6 @@ > 656B84D70AEA1CE900A095B4 /* network */, > 1A2E6E560CC551E0004A2062 /* sql */, > B2C3D9EC0D006C1D00EF6F26 /* text */, >- E188235F2031F50F00B42DF3 /* vr */, > DFDB912CF8E88A6DA1AD264F /* AbortableTaskQueue.h */, > 49AE2D94134EE5F90072920A /* CalculationValue.cpp */, > 49AE2D95134EE5F90072920A /* CalculationValue.h */, >@@ -28904,6 +28920,17 @@ > files = ( > 72144332223EC85F00F12FF7 /* (null) in Headers */, > 72144331223EC85400F12FF7 /* (null) in Headers */, >+ 2DDE1CE41F574AE900D1A365 /* (null) in Headers */, >+ 2DDE1CF81F574C3900D1A365 /* (null) in Headers */, >+ 2DDE1CFA1F574C3E00D1A365 /* (null) in Headers */, >+ 2DDE1CFC1F574CEE00D1A365 /* (null) in Headers */, >+ 2DDE1CFE1F574CF300D1A365 /* (null) in Headers */, >+ 2DDE1D001F574CF700D1A365 /* (null) in Headers */, >+ 2DDE1CE31F574AE500D1A365 /* (null) in Headers */, >+ 2DDE1D021F574D0000D1A365 /* (null) in Headers */, >+ 2DDE1D041F574D0500D1A365 /* (null) in Headers */, >+ 2DDE1D061F574D0A00D1A365 /* (null) in Headers */, >+ 2DDE1D081F574D0E00D1A365 /* (null) in Headers */, > 7CD0E2B81F80A4820016A4CE /* AbortController.h in Headers */, > 7CD0E2BF1F80A56E0016A4CE /* AbortSignal.h in Headers */, > 46B95195207D633400A7D2DD /* AbstractDOMWindow.h in Headers */, >@@ -30259,8 +30286,7 @@ > 7C7903B31F86F95C00463A70 /* ImageBitmapRenderingContext.h in Headers */, > 318EAD4D1FA91380008CEF86 /* ImageBitmapRenderingContextSettings.h in Headers */, > B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */, >- 22BD9F7F1353625C009BD102 /* ImageBufferData.h in Headers */, >- 22BD9F81135364FE009BD102 /* ImageBufferDataCG.h in Headers */, >+ 72BAC3AE23E1F0B0008D741C /* ImageBufferBackend.h in Headers */, > CD3E21DD2183444A00E66F55 /* ImageBufferUtilitiesCG.h in Headers */, > 2D25396318CE7F6200270222 /* ImageControlsButtonElementMac.h in Headers */, > 510192D618B6B9B7007FC7A1 /* ImageControlsRootElement.h in Headers */, >@@ -31165,17 +31191,6 @@ > BE8EF04D171C9014009B48C3 /* JSVideoTrackList.h in Headers */, > 46E791491F97E01A00199739 /* JSVisibilityState.h in Headers */, > 7779BD961F32246A00C21417 /* JSVisualViewport.h in Headers */, >- 2DDE1CE41F574AE900D1A365 /* JSVRDisplay.h in Headers */, >- 2DDE1CF81F574C3900D1A365 /* JSVRDisplayCapabilities.h in Headers */, >- 2DDE1CFA1F574C3E00D1A365 /* JSVRDisplayEvent.h in Headers */, >- 2DDE1CFC1F574CEE00D1A365 /* JSVRDisplayEventReason.h in Headers */, >- 2DDE1CFE1F574CF300D1A365 /* JSVREye.h in Headers */, >- 2DDE1D001F574CF700D1A365 /* JSVREyeParameters.h in Headers */, >- 2DDE1CE31F574AE500D1A365 /* JSVRFieldOfView.h in Headers */, >- 2DDE1D021F574D0000D1A365 /* JSVRFrameData.h in Headers */, >- 2DDE1D041F574D0500D1A365 /* JSVRLayerInit.h in Headers */, >- 2DDE1D061F574D0A00D1A365 /* JSVRPose.h in Headers */, >- 2DDE1D081F574D0E00D1A365 /* JSVRStageParameters.h in Headers */, > BE20508218A460C30080647E /* JSVTTCue.h in Headers */, > 7AF9B20D18CFB5F400C64BEF /* JSVTTRegion.h in Headers */, > 7AF9B20F18CFB5F400C64BEF /* JSVTTRegionList.h in Headers */, >@@ -31933,6 +31948,7 @@ > BCEA4876097D93020094C9E4 /* RenderImage.h in Headers */, > 08F2F00A1213E61700DCEC48 /* RenderImageResource.h in Headers */, > 08641D4812142F7D008DE9F6 /* RenderImageResourceStyleImage.h in Headers */, >+ 7239406523E8828600E3B545 /* RenderingBackend.h in Headers */, > 7299BC6823D6A53E00CC6883 /* RenderingMode.h in Headers */, > 556C7C4B22123997009B06CA /* RenderingUpdateScheduler.h in Headers */, > BCEA4878097D93020094C9E4 /* RenderInline.h in Headers */, >diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/Source/WebCore/bindings/js/SerializedScriptValue.cpp >index c4c7e288277266ddec752041212b5e2bc5faa358..25d69f94a67fb91bcc48bc7e8596d758f6f5e27e 100644 >--- a/Source/WebCore/bindings/js/SerializedScriptValue.cpp >+++ b/Source/WebCore/bindings/js/SerializedScriptValue.cpp >@@ -943,13 +943,13 @@ private: > } > > const IntSize& logicalSize = buffer->logicalSize(); >- auto imageData = buffer->getPremultipliedImageData(IntRect(0, 0, logicalSize.width(), logicalSize.height())); >+ auto imageData = buffer->getImageData(AlphaPremultiplication::Premultiplied, { IntPoint::zero(), logicalSize }); > if (!imageData) { > code = SerializationReturnCode::ValidationError; > return; > } > >- RefPtr<ArrayBuffer> arrayBuffer = imageData->possiblySharedBuffer(); >+ RefPtr<ArrayBuffer> arrayBuffer = imageData->data()->possiblySharedBuffer(); > if (!arrayBuffer) { > code = SerializationReturnCode::ValidationError; > return; >@@ -2865,19 +2865,25 @@ private: > return JSValue(); > } > >- auto imageData = Uint8ClampedArray::tryCreate(WTFMove(arrayBuffer), 0, arrayBuffer->byteLength()); >- if (!imageData) { >+ auto array = Uint8ClampedArray::tryCreate(WTFMove(arrayBuffer), 0, arrayBuffer->byteLength()); >+ if (!array) { > fail(); > return JSValue(); > } > >+ auto imageData = ImageData::create(IntSize(logicalWidth, logicalHeight), array.releaseNonNull()); >+ if (!imageData) { >+ fail(); >+ return JSValue(); >+ } >+ > auto buffer = ImageBuffer::create(FloatSize(logicalWidth, logicalHeight), RenderingMode::Unaccelerated, resolutionScale); > if (!buffer) { > fail(); > return JSValue(); > } > >- buffer->putByteArray(*imageData, AlphaPremultiplication::Premultiplied, IntSize(logicalWidth, logicalHeight), IntRect(0, 0, logicalWidth, logicalHeight), IntPoint()); >+ buffer->putImageData(AlphaPremultiplication::Premultiplied, *imageData, { IntPoint::zero(), imageData->size() }); > > auto bitmap = ImageBitmap::create({ WTFMove(buffer), static_cast<bool>(originClean) }); > return getJSValue(bitmap); >diff --git a/Source/WebCore/html/CanvasBase.cpp b/Source/WebCore/html/CanvasBase.cpp >index d2ad41e871ac5a0bcb4d69c152534639a736145d..162b2942f666a932460b06e76d0836e43c017170 100644 >--- a/Source/WebCore/html/CanvasBase.cpp >+++ b/Source/WebCore/html/CanvasBase.cpp >@@ -191,8 +191,8 @@ std::unique_ptr<ImageBuffer> CanvasBase::setImageBuffer(std::unique_ptr<ImageBuf > returnBuffer = std::exchange(m_imageBuffer, WTFMove(buffer)); > } > >- if (m_imageBuffer && m_size != m_imageBuffer->internalSize()) >- m_size = m_imageBuffer->internalSize(); >+ if (m_imageBuffer && m_size != m_imageBuffer->backendSize()) >+ m_size = m_imageBuffer->backendSize(); > > size_t previousMemoryCost = m_imageBufferCost; > m_imageBufferCost = memoryCost(); >diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp >index f5e7650069a6d8690d943dee26bb361f9189ce31..42a65d3a9e75445442e659f8c9a5a75d2e839514 100644 >--- a/Source/WebCore/html/HTMLCanvasElement.cpp >+++ b/Source/WebCore/html/HTMLCanvasElement.cpp >@@ -33,6 +33,7 @@ > #include "CanvasGradient.h" > #include "CanvasPattern.h" > #include "CanvasRenderingContext2D.h" >+#include "DisplayListDrawingContext.h" > #include "Document.h" > #include "Frame.h" > #include "FrameLoaderClient.h" >@@ -349,9 +350,6 @@ CanvasRenderingContext2D* HTMLCanvasElement::createContext2d(const String& type) > > m_context = CanvasRenderingContext2D::create(*this, document().inQuirksMode()); > >- downcast<CanvasRenderingContext2D>(*m_context).setUsesDisplayListDrawing(m_usesDisplayListDrawing); >- downcast<CanvasRenderingContext2D>(*m_context).setTracksDisplayListReplay(m_tracksDisplayListReplay); >- > #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS) > // Need to make sure a RenderLayer and compositing layer get created for the Canvas. > invalidateStyleAndLayerComposition(); >@@ -822,39 +820,27 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const > > void HTMLCanvasElement::setUsesDisplayListDrawing(bool usesDisplayListDrawing) > { >- if (usesDisplayListDrawing == m_usesDisplayListDrawing) >- return; >- > m_usesDisplayListDrawing = usesDisplayListDrawing; >- >- if (is<CanvasRenderingContext2D>(m_context.get())) >- downcast<CanvasRenderingContext2D>(*m_context).setUsesDisplayListDrawing(m_usesDisplayListDrawing); > } > > void HTMLCanvasElement::setTracksDisplayListReplay(bool tracksDisplayListReplay) > { >- if (tracksDisplayListReplay == m_tracksDisplayListReplay) >- return; >- > m_tracksDisplayListReplay = tracksDisplayListReplay; >- >- if (is<CanvasRenderingContext2D>(m_context.get())) >- downcast<CanvasRenderingContext2D>(*m_context).setTracksDisplayListReplay(m_tracksDisplayListReplay); >+ if (buffer() && buffer()->drawingContext()) >+ buffer()->drawingContext()->setTracksDisplayListReplay(m_tracksDisplayListReplay); > } > > String HTMLCanvasElement::displayListAsText(DisplayList::AsTextFlags flags) const > { >- if (is<CanvasRenderingContext2D>(m_context.get())) >- return downcast<CanvasRenderingContext2D>(*m_context).displayListAsText(flags); >- >+ if (buffer() && buffer()->drawingContext()) >+ return buffer()->drawingContext()->displayList().asText(flags); > return String(); > } > > String HTMLCanvasElement::replayDisplayListAsText(DisplayList::AsTextFlags flags) const > { >- if (is<CanvasRenderingContext2D>(m_context.get())) >- return downcast<CanvasRenderingContext2D>(*m_context).replayDisplayListAsText(flags); >- >+ if (buffer() && buffer()->drawingContext() && buffer()->drawingContext()->replayDisplayList()) >+ return buffer()->drawingContext()->replayDisplayList()->asText(flags); > return String(); > } > >@@ -889,11 +875,22 @@ void HTMLCanvasElement::createImageBuffer() const > if (!width() || !height()) > return; > >- RenderingMode renderingMode = shouldAccelerate(size()) ? RenderingMode::Accelerated : RenderingMode::Unaccelerated; >- > auto hostWindow = (document().view() && document().view()->root()) ? document().view()->root()->hostWindow() : nullptr; >+ >+ // FIXME: Add a new setting for DisplayList drawing on canvas. >+ bool usesDisplayListDrawing = m_usesDisplayListDrawing.valueOr(document().settings().displayListDrawingEnabled()); >+ >+ RenderingMode renderingMode; >+ if (usesDisplayListDrawing) >+ renderingMode = shouldAccelerate(size()) ? RenderingMode::DisplayListAccelerated : RenderingMode::DisplayList; >+ else >+ renderingMode = shouldAccelerate(size()) ? RenderingMode::Accelerated : RenderingMode::Unaccelerated; >+ > setImageBuffer(ImageBuffer::create(size(), renderingMode, 1, ColorSpace::SRGB, hostWindow)); > >+ if (buffer() && buffer()->drawingContext()) >+ buffer()->drawingContext()->setTracksDisplayListReplay(m_tracksDisplayListReplay); >+ > #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS) > if (m_context && m_context->is2d()) { > // Recalculate compositing requirements if acceleration state changed. >diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h >index b528645c65874cd0ca09344461b454d560506326..42134a122941496bf31bcdd79c6bc5c391a78a45 100644 >--- a/Source/WebCore/html/HTMLCanvasElement.h >+++ b/Source/WebCore/html/HTMLCanvasElement.h >@@ -161,7 +161,7 @@ private: > > bool m_ignoreReset { false }; > >- bool m_usesDisplayListDrawing { false }; >+ Optional<bool> m_usesDisplayListDrawing; > bool m_tracksDisplayListReplay { false }; > > std::unique_ptr<CanvasRenderingContext> m_context; >diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp >index d4947120832310c7c0d7bef1c879da3ffb293f0a..d2b8db814d3134186412fa5d8aeaf7a2380b1285 100644 >--- a/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp >+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp >@@ -2158,11 +2158,6 @@ ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::createImageData(flo > } > > ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(float sx, float sy, float sw, float sh) const >-{ >- return getImageData(ImageBuffer::LogicalCoordinateSystem, sx, sy, sw, sh); >-} >- >-ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(ImageBuffer::CoordinateSystem coordinateSystem, float sx, float sy, float sw, float sh) const > { > if (!canvasBase().originClean()) { > static NeverDestroyed<String> consoleMessage(MAKE_STATIC_STRING_IMPL("Unable to get image data from canvas because the canvas has been tainted by cross-origin data.")); >@@ -2196,8 +2191,8 @@ ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(ImageB > if (!buffer) > return createEmptyImageData(imageDataRect.size()); > >- auto byteArray = buffer->getUnmultipliedImageData(imageDataRect, nullptr, coordinateSystem); >- if (!byteArray) { >+ auto imageData = buffer->getImageData(AlphaPremultiplication::Unpremultiplied, imageDataRect); >+ if (!imageData) { > StringBuilder consoleMessage; > consoleMessage.appendLiteral("Unable to get image data from canvas. Requested size was "); > consoleMessage.appendNumber(imageDataRect.width()); >@@ -2208,7 +2203,7 @@ ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2DBase::getImageData(ImageB > return Exception { InvalidStateError }; > } > >- return ImageData::create(imageDataRect.size(), byteArray.releaseNonNull()); >+ return imageData; > } > > void CanvasRenderingContext2DBase::putImageData(ImageData& data, float dx, float dy) >@@ -2217,11 +2212,6 @@ void CanvasRenderingContext2DBase::putImageData(ImageData& data, float dx, float > } > > void CanvasRenderingContext2DBase::putImageData(ImageData& data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight) >-{ >- putImageData(data, ImageBuffer::LogicalCoordinateSystem, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight); >-} >- >-void CanvasRenderingContext2DBase::putImageData(ImageData& data, ImageBuffer::CoordinateSystem coordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight) > { > ImageBuffer* buffer = canvasBase().buffer(); > if (!buffer) >@@ -2245,7 +2235,7 @@ void CanvasRenderingContext2DBase::putImageData(ImageData& data, ImageBuffer::Co > IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy)); > IntRect destRect = enclosingIntRect(clipRect); > destRect.move(destOffset); >- destRect.intersect(IntRect(IntPoint(), coordinateSystem == ImageBuffer::LogicalCoordinateSystem ? buffer->logicalSize() : buffer->internalSize())); >+ destRect.intersect(IntRect(IntPoint(), buffer->logicalSize())); > if (destRect.isEmpty()) > return; > IntRect sourceRect(destRect); >@@ -2253,7 +2243,7 @@ void CanvasRenderingContext2DBase::putImageData(ImageData& data, ImageBuffer::Co > sourceRect.intersect(IntRect(0, 0, data.width(), data.height())); > > if (!sourceRect.isEmpty()) >- buffer->putByteArray(*data.data(), AlphaPremultiplication::Unpremultiplied, IntSize(data.width(), data.height()), sourceRect, IntPoint(destOffset), coordinateSystem); >+ buffer->putImageData(AlphaPremultiplication::Unpremultiplied, data, sourceRect, IntPoint(destOffset)); > > didDraw(destRect, CanvasDidDrawApplyNone); // ignore transform, shadow and clip > } >diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h b/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h >index 3dfc9c9fce52be8892bf498ae6722187f1bee91d..db3fac8b08b703bd541fc72f4d31bd51773504d0 100644 >--- a/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h >+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2DBase.h >@@ -371,9 +371,6 @@ protected: > > template<class T> void fullCanvasCompositedDrawImage(T&, const FloatRect&, const FloatRect&, CompositeOperator); > >- ExceptionOr<RefPtr<ImageData>> getImageData(ImageBuffer::CoordinateSystem, float sx, float sy, float sw, float sh) const; >- void putImageData(ImageData&, ImageBuffer::CoordinateSystem, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight); >- > bool isAccelerated() const override; > > bool hasInvertibleTransform() const override { return state().hasInvertibleTransform; } >diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp >index f586ccb178c76e578c2130846a1fbfa7effd7af5..637e77c5fedab33c5bdb80c6fd0e11ab7f4a8217 100644 >--- a/Source/WebCore/page/Chrome.cpp >+++ b/Source/WebCore/page/Chrome.cpp >@@ -494,6 +494,13 @@ void Chrome::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) > m_client.setCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves); > } > >+RenderingBackend* Chrome::sharedRenderingBackend() const >+{ >+ if (!m_renderingBackend) >+ m_renderingBackend = m_client.createRenderingBackend(); >+ return m_renderingBackend.get(); >+} >+ > PlatformDisplayID Chrome::displayID() const > { > return m_displayID; >diff --git a/Source/WebCore/page/Chrome.h b/Source/WebCore/page/Chrome.h >index 662be00fa0abae8b7ba7d668d4470ec51361af49..6cfcaeca285c4ebc5e2244e8ebd64bac9a762e22 100644 >--- a/Source/WebCore/page/Chrome.h >+++ b/Source/WebCore/page/Chrome.h >@@ -83,6 +83,8 @@ public: > void setCursor(const Cursor&) override; > void setCursorHiddenUntilMouseMoves(bool) override; > >+ RenderingBackend* sharedRenderingBackend() const override; >+ > void scheduleAnimation() override { } > > PlatformDisplayID displayID() const override; >@@ -195,6 +197,7 @@ private: > #if PLATFORM(IOS_FAMILY) > bool m_isDispatchViewportDataDidChangeSuppressed { false }; > #endif >+ mutable std::unique_ptr<RenderingBackend> m_renderingBackend; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h >index 989baf4a7d7f33545932bd93043ef43ba7aa512a..b59ce13d9ec330193d80347c0cf871d9258ca5ec 100644 >--- a/Source/WebCore/page/ChromeClient.h >+++ b/Source/WebCore/page/ChromeClient.h >@@ -43,6 +43,7 @@ > #include "PopupMenuClient.h" > #include "RegistrableDomain.h" > #include "RenderEmbeddedObject.h" >+#include "RenderingBackend.h" > #include "ScrollTypes.h" > #include "ScrollingCoordinator.h" > #include "SearchPopupMenu.h" >@@ -305,6 +306,8 @@ public: > virtual RefPtr<DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID) const { return nullptr; } > #endif > >+ virtual std::unique_ptr<RenderingBackend> createRenderingBackend() const { return nullptr; } >+ > // Pass nullptr as the GraphicsLayer to detatch the root layer. > virtual void attachRootGraphicsLayer(Frame&, GraphicsLayer*) = 0; > virtual void attachViewOverlayGraphicsLayer(GraphicsLayer*) = 0; >diff --git a/Source/WebCore/page/PageConsoleClient.cpp b/Source/WebCore/page/PageConsoleClient.cpp >index 4c3533091619dc643f872909cb71f7828ef85bbc..e60cde14d1a7c6c30428907507c610be55de1a22 100644 >--- a/Source/WebCore/page/PageConsoleClient.cpp >+++ b/Source/WebCore/page/PageConsoleClient.cpp >@@ -376,7 +376,7 @@ void PageConsoleClient::screenshot(JSC::JSGlobalObject* lexicalGlobalObject, Ref > auto sourceSize = imageData->size(); > if (auto imageBuffer = ImageBuffer::create(sourceSize, RenderingMode::Unaccelerated)) { > IntRect sourceRect(IntPoint(), sourceSize); >- imageBuffer->putByteArray(*imageData->data(), AlphaPremultiplication::Unpremultiplied, sourceSize, sourceRect, IntPoint()); >+ imageBuffer->putImageData(AlphaPremultiplication::Unpremultiplied, *imageData, sourceRect); > dataURL = imageBuffer->toDataURL("image/png"_s, WTF::nullopt, PreserveResolution::Yes); > } > } >diff --git a/Source/WebCore/platform/Cairo.cmake b/Source/WebCore/platform/Cairo.cmake >index 9a3a8bf943ad6586da43ced0da7e63f055ab9a5d..12a2d74ffbe8fcc73f068bbfcba0054077571772 100644 >--- a/Source/WebCore/platform/Cairo.cmake >+++ b/Source/WebCore/platform/Cairo.cmake >@@ -13,7 +13,10 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS > platform/graphics/cairo/CairoOperations.h > platform/graphics/cairo/CairoUtilities.h > platform/graphics/cairo/GraphicsContextImplCairo.h >- platform/graphics/cairo/ImageBufferDataCairo.h >+ platform/graphics/cairo/ImageBufferCairoBackend.h >+ platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.h >+ platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h >+ platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h > platform/graphics/cairo/PlatformContextCairo.h > platform/graphics/cairo/RefPtrCairo.h > ) >diff --git a/Source/WebCore/platform/HostWindow.h b/Source/WebCore/platform/HostWindow.h >index 2cfecadc24d982a8616374b76a0e4fb0fff7a9d4..89865346cf480f806c5c0ce93521de692081804c 100644 >--- a/Source/WebCore/platform/HostWindow.h >+++ b/Source/WebCore/platform/HostWindow.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2008 Apple Inc. All rights reserved. >+ * Copyright (C) 2008-2020 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -23,14 +23,14 @@ > * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > >-#ifndef HostWindow_h >-#define HostWindow_h >+#pragma once > > #include "Widget.h" > > namespace WebCore { > > class Cursor; >+class RenderingBackend; > > class HostWindow { > WTF_MAKE_NONCOPYABLE(HostWindow); WTF_MAKE_FAST_ALLOCATED; >@@ -64,6 +64,8 @@ public: > > virtual void setCursorHiddenUntilMouseMoves(bool) = 0; > >+ virtual RenderingBackend* sharedRenderingBackend() const = 0; >+ > virtual void scheduleAnimation() = 0; > > virtual PlatformDisplayID displayID() const = 0; >@@ -75,5 +77,3 @@ public: > }; > > } // namespace WebCore >- >-#endif // HostWindow_h >diff --git a/Source/WebCore/platform/SourcesCairo.txt b/Source/WebCore/platform/SourcesCairo.txt >index f90d246ec59b4f8a8e138b72240cf202583192c4..6fa4ffe1460ea713821bca36226d26a97e5d9989 100644 >--- a/Source/WebCore/platform/SourcesCairo.txt >+++ b/Source/WebCore/platform/SourcesCairo.txt >@@ -30,7 +30,10 @@ platform/graphics/cairo/GradientCairo.cpp > platform/graphics/cairo/GraphicsContextGLCairo.cpp > platform/graphics/cairo/GraphicsContextCairo.cpp > platform/graphics/cairo/GraphicsContextImplCairo.cpp >-platform/graphics/cairo/ImageBufferCairo.cpp >+platform/graphics/cairo/ImageBufferCairoBackend.cpp >+platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.cpp >+platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp >+platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp > platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp > platform/graphics/cairo/IntRectCairo.cpp > platform/graphics/cairo/NativeImageCairo.cpp >diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp >index 482244a4f2bdcede7c874cd1b50ea914b1499a22..ddd5c6c7345a2c0d8bd9a8e4efb4e3cb99587c6b 100644 >--- a/Source/WebCore/platform/graphics/BitmapImage.cpp >+++ b/Source/WebCore/platform/graphics/BitmapImage.cpp >@@ -165,12 +165,7 @@ NativeImagePtr BitmapImage::nativeImageForCurrentFrameRespectingOrientation(cons > return image; > > buffer->context().drawNativeImage(image, rect.size(), rect, rect, { orientation }); >- >-#if USE(CG) || USE(DIRECT2D) > return ImageBuffer::sinkIntoNativeImage(WTFMove(buffer)); >-#elif USE(CAIRO) >- return buffer->nativeImage(); >-#endif > } > > #if USE(CG) >diff --git a/Source/WebCore/platform/graphics/ContextualImageBuffer.h b/Source/WebCore/platform/graphics/ContextualImageBuffer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..28f32782105a84e92562052b9d4c70ad6f658942 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/ContextualImageBuffer.h >@@ -0,0 +1,181 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ImageBuffer.h" >+#include "ImageData.h" >+ >+namespace WebCore { >+ >+template<typename BackendType> >+class ContextualImageBuffer : public ImageBuffer { >+public: >+ template<typename ImageBufferType = ContextualImageBuffer, typename... Arguments> >+ static std::unique_ptr<ImageBuffer> create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow, Arguments&&... arguments) >+ { >+ auto backend = BackendType::create(size, resolutionScale, colorSpace, hostWindow); >+ if (!backend) >+ return nullptr; >+ return std::unique_ptr<ImageBufferType>(new ImageBufferType(WTFMove(backend), std::forward<Arguments>(arguments)...)); >+ } >+ >+ template<typename ImageBufferType = ContextualImageBuffer, typename... Arguments> >+ static std::unique_ptr<ImageBuffer> create(const FloatSize& size, const GraphicsContext& context, Arguments&&... arguments) >+ { >+ auto backend = BackendType::create(size, context); >+ if (!backend) >+ return nullptr; >+ return std::unique_ptr<ImageBufferType>(new ImageBufferType(WTFMove(backend), std::forward<Arguments>(arguments)...)); >+ } >+ >+protected: >+ ContextualImageBuffer(std::unique_ptr<BackendType>&& backend) >+ : m_backend(WTFMove(backend)) >+ { >+ } >+ >+ ContextualImageBuffer() = default; >+ >+ virtual BackendType* ensureBackend() const { return m_backend.get(); } >+ >+ GraphicsContext& context() const override >+ { >+ ASSERT(m_backend); >+ return m_backend->context(); >+ } >+ >+ void flushContext() override >+ { >+ flushDrawingContext(); >+ m_backend->flushContext(); >+ } >+ >+ AffineTransform baseTransform() const override { return m_backend->baseTransform(); } >+ IntSize logicalSize() const override { return m_backend->logicalSize(); } >+ IntSize backendSize() const override { return m_backend->backendSize(); } >+ float resolutionScale() const override { return m_backend->resolutionScale(); } >+ >+ size_t memoryCost() const override { return m_backend->memoryCost(); } >+ size_t externalMemoryCost() const override { return m_backend->externalMemoryCost(); } >+ >+ NativeImagePtr copyNativeImage(BackingStoreCopy copyBehavior = CopyBackingStore) const override >+ { >+ const_cast<ContextualImageBuffer&>(*this).flushDrawingContext(); >+ return m_backend->copyNativeImage(copyBehavior); >+ } >+ >+ RefPtr<Image> copyImage(BackingStoreCopy copyBehavior = CopyBackingStore, PreserveResolution preserveResolution = PreserveResolution::No) const override >+ { >+ const_cast<ContextualImageBuffer&>(*this).flushDrawingContext(); >+ return m_backend->copyImage(copyBehavior, preserveResolution); >+ } >+ >+ void draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) override >+ { >+ flushDrawingContext(); >+ m_backend->draw(destContext, destRect, srcRect, options); >+ } >+ >+ void drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options) override >+ { >+ flushDrawingContext(); >+ m_backend->drawPattern(destContext, destRect, srcRect, patternTransform, phase, spacing, options); >+ } >+ >+ NativeImagePtr sinkIntoNativeImage() override >+ { >+ flushDrawingContext(); >+ return m_backend->sinkIntoNativeImage(); >+ } >+ >+ RefPtr<Image> sinkIntoImage(PreserveResolution preserveResolution = PreserveResolution::No) override >+ { >+ flushDrawingContext(); >+ return m_backend->sinkIntoImage(preserveResolution); >+ } >+ >+ void drawConsuming(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) override >+ { >+ flushDrawingContext(); >+ m_backend->drawConsuming(destContext, destRect, srcRect, options); >+ } >+ >+ void convertToLuminanceMask() override >+ { >+ flushDrawingContext(); >+ m_backend->convertToLuminanceMask(); >+ } >+ >+ void transformColorSpace(ColorSpace srcColorSpace, ColorSpace destColorSpace) override >+ { >+ flushDrawingContext(); >+ m_backend->transformColorSpace(srcColorSpace, destColorSpace); >+ } >+ >+ String toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution preserveResolution) const override >+ { >+ const_cast<ContextualImageBuffer&>(*this).flushContext(); >+ return m_backend->toDataURL(mimeType, quality, preserveResolution); >+ } >+ >+ Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const override >+ { >+ const_cast<ContextualImageBuffer&>(*this).flushContext(); >+ return m_backend->toData(mimeType, quality); >+ } >+ >+ Vector<uint8_t> toBGRAData() const override >+ { >+ const_cast<ContextualImageBuffer&>(*this).flushContext(); >+ return m_backend->toBGRAData(); >+ } >+ >+ RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const override >+ { >+ const_cast<ContextualImageBuffer&>(*this).flushContext(); >+ return m_backend->getImageData(outputFormat, srcRect); >+ } >+ >+ void putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint = { }) override >+ { >+ flushContext(); >+ m_backend->putImageData(inputFormat, imageData, srcRect, destPoint); >+ } >+ >+ PlatformLayer* platformLayer() const override >+ { >+ return m_backend->platformLayer(); >+ } >+ >+ bool copyToPlatformTexture(GraphicsContextGLOpenGL& context, GCGLenum target, PlatformGLObject destinationTexture, GCGLenum internalformat, bool premultiplyAlpha, bool flipY) const override >+ { >+ return m_backend->copyToPlatformTexture(context, target, destinationTexture, internalformat, premultiplyAlpha, flipY); >+ } >+ >+ std::unique_ptr<BackendType> m_backend; >+}; >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/DisplayListImageBuffer.h b/Source/WebCore/platform/graphics/DisplayListImageBuffer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9db0f0dfbc47ca12d73c43786ea1a8979fd0b545 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/DisplayListImageBuffer.h >@@ -0,0 +1,72 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ContextualImageBuffer.h" >+#include "DisplayListDrawingContext.h" >+ >+namespace WebCore { >+ >+template<typename BackendType> >+class DisplayListImageBuffer : public ContextualImageBuffer<BackendType> , public DisplayList::DrawingContext { >+ using BaseContextualImageBuffer = ContextualImageBuffer<BackendType>; >+ >+public: >+ static std::unique_ptr<ImageBuffer> create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+ { >+ return BaseContextualImageBuffer::template create<DisplayListImageBuffer>(size, resolutionScale, colorSpace, hostWindow, size); >+ } >+ >+ static std::unique_ptr<ImageBuffer> create(const FloatSize& size, const GraphicsContext& context) >+ { >+ return BaseContextualImageBuffer::template create<DisplayListImageBuffer>(size, context, size); >+ } >+ >+ DisplayListImageBuffer(std::unique_ptr<BackendType>&& dataBackend, const FloatSize& size) >+ : BaseContextualImageBuffer(WTFMove(dataBackend)) >+ , DisplayList::DrawingContext(size) >+ { >+ } >+ >+ ~DisplayListImageBuffer() >+ { >+ flushDrawingContext(); >+ } >+ >+ DisplayList::DrawingContext* drawingContext() override { return this; } >+ >+ GraphicsContext& context() const override >+ { >+ return DisplayList::DrawingContext::context(); >+ } >+ >+ void flushDrawingContext() override >+ { >+ DisplayList::DrawingContext::replayDisplayList(BaseContextualImageBuffer::context()); >+ } >+}; >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/ImageBuffer.cpp b/Source/WebCore/platform/graphics/ImageBuffer.cpp >index 20b9810c29141e473e6a888bc80c1417aeac2faf..afa8b5a5d08e56a863d40a9dde815950d282dc61 100644 >--- a/Source/WebCore/platform/graphics/ImageBuffer.cpp >+++ b/Source/WebCore/platform/graphics/ImageBuffer.cpp >@@ -1,7 +1,7 @@ > /* > * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> > * Copyright (C) Research In Motion Limited 2011. All rights reserved. >- * Copyright (C) 2016-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2016-2020 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -28,44 +28,67 @@ > #include "config.h" > #include "ImageBuffer.h" > >-#include "ColorUtilities.h" > #include "GraphicsContext.h" >-#include "IntRect.h" >-#include <wtf/IsoMallocInlines.h> >-#include <wtf/MathExtras.h> >+#include "PlatformImageBuffer.h" >+#include "RenderingBackend.h" > > namespace WebCore { > > static const float MaxClampedLength = 4096; > static const float MaxClampedArea = MaxClampedLength * MaxClampedLength; > >-WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBuffer); >- > std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) > { >- bool success = false; >- std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(size, resolutionScale, colorSpace, renderingMode, hostWindow, success)); >- if (!success) >+ return RenderingBackend::sharedRenderingBackend(hostWindow).createImageBuffer(size, renderingMode, resolutionScale, colorSpace, hostWindow); >+} >+ >+std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, const GraphicsContext& context) >+{ >+ return RenderingBackend::sharedRenderingBackend().createImageBuffer(size, context); >+} >+ >+std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const GraphicsContext& context) >+{ >+ if (size.isEmpty()) > return nullptr; >- return buffer; >+ >+ IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context); >+ >+ auto imageBuffer = ImageBuffer::create(scaledSize, context); >+ if (!imageBuffer) >+ return nullptr; >+ >+ // Set up a corresponding scale factor on the graphics context. >+ imageBuffer->context().scale(scaledSize / size); >+ return imageBuffer; >+ > } > >-#if USE(DIRECT2D) >-std::unique_ptr<ImageBuffer> ImageBuffer::create(const FloatSize& size, RenderingMode renderingMode, const GraphicsContext* targetContext, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, ColorSpace colorSpace, const GraphicsContext& context) > { >- bool success = false; >- std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(size, resolutionScale, colorSpace, renderingMode, hostWindow, targetContext, success)); >- if (!success) >+ if (size.isEmpty()) > return nullptr; >- return buffer; >+ >+ IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context); >+ >+ auto imageBuffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context); >+ if (!imageBuffer) >+ return nullptr; >+ >+ // Set up a corresponding scale factor on the graphics context. >+ imageBuffer->context().scale(scaledSize / size); >+ return imageBuffer; >+} >+ >+std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const GraphicsContext& context) >+{ >+ return ImageBuffer::create(size, context.renderingMode(), resolutionScale, colorSpace); > } >-#endif > > bool ImageBuffer::sizeNeedsClamping(const FloatSize& size) > { > if (size.isEmpty()) > return false; >- > return floorf(size.height()) * floorf(size.width()) > MaxClampedArea; > } > >@@ -105,91 +128,12 @@ FloatRect ImageBuffer::clampedRect(const FloatRect& rect) > return FloatRect(rect.location(), clampedSize(rect.size())); > } > >-#if !USE(CG) && !USE(CAIRO) >-Vector<uint8_t> ImageBuffer::toBGRAData() const >-{ >- // FIXME: Implement this for other backends. >- return { }; >-} >-#endif >- >-#if !(USE(CG) || USE(DIRECT2D)) >-void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace) >-{ >- if (srcColorSpace == dstColorSpace) >- return; >- >- // only sRGB <-> linearRGB are supported at the moment >- if ((srcColorSpace != ColorSpace::LinearRGB && srcColorSpace != ColorSpace::SRGB) >- || (dstColorSpace != ColorSpace::LinearRGB && dstColorSpace != ColorSpace::SRGB)) >- return; >- >- if (dstColorSpace == ColorSpace::LinearRGB) { >- static const std::array<uint8_t, 256> linearRgbLUT = [] { >- std::array<uint8_t, 256> array; >- for (unsigned i = 0; i < 256; i++) { >- float color = i / 255.0f; >- color = sRGBToLinearColorComponent(color); >- array[i] = static_cast<uint8_t>(round(color * 255)); >- } >- return array; >- }(); >- platformTransformColorSpace(linearRgbLUT); >- } else if (dstColorSpace == ColorSpace::SRGB) { >- static const std::array<uint8_t, 256> deviceRgbLUT= [] { >- std::array<uint8_t, 256> array; >- for (unsigned i = 0; i < 256; i++) { >- float color = i / 255.0f; >- color = linearToSRGBColorComponent(color); >- array[i] = static_cast<uint8_t>(round(color * 255)); >- } >- return array; >- }(); >- platformTransformColorSpace(deviceRgbLUT); >- } >-} >- >-#endif // USE(CG) >- >-inline void ImageBuffer::genericConvertToLuminanceMask() >-{ >- IntRect luminanceRect(IntPoint(), internalSize()); >- auto srcPixelArray = getUnmultipliedImageData(luminanceRect); >- if (!srcPixelArray) >- return; >- >- unsigned pixelArrayLength = srcPixelArray->length(); >- for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { >- uint8_t a = srcPixelArray->item(pixelOffset + 3); >- if (!a) >- continue; >- uint8_t r = srcPixelArray->item(pixelOffset); >- uint8_t g = srcPixelArray->item(pixelOffset + 1); >- uint8_t b = srcPixelArray->item(pixelOffset + 2); >- >- double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); >- srcPixelArray->set(pixelOffset + 3, luma); >- } >- putByteArray(*srcPixelArray, AlphaPremultiplication::Unpremultiplied, luminanceRect.size(), luminanceRect, IntPoint()); >-} >- >-void ImageBuffer::convertToLuminanceMask() >-{ >- // Add platform specific functions with platformConvertToLuminanceMask here later. >- genericConvertToLuminanceMask(); >-} >- >-#if !USE(CAIRO) >-PlatformLayer* ImageBuffer::platformLayer() const >-{ >- return 0; >-} >- >-bool ImageBuffer::copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) >+IntSize ImageBuffer::compatibleBufferSize(const FloatSize& size, const GraphicsContext& context) > { >- return false; >+ // Enlarge the buffer size if the context's transform is scaling it so we need a higher >+ // resolution than one pixel per unit. >+ return expandedIntSize(size * context.scaleFactor()); > } >-#endif > > std::unique_ptr<ImageBuffer> ImageBuffer::copyRectToBuffer(const FloatRect& rect, ColorSpace colorSpace, const GraphicsContext& context) > { >@@ -206,50 +150,19 @@ std::unique_ptr<ImageBuffer> ImageBuffer::copyRectToBuffer(const FloatRect& rect > return buffer; > } > >-std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, ColorSpace colorSpace, const GraphicsContext& context) >+NativeImagePtr ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer) > { >- if (size.isEmpty()) >- return nullptr; >- >- IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context); >- >- auto buffer = ImageBuffer::createCompatibleBuffer(scaledSize, 1, colorSpace, context); >- if (!buffer) >- return nullptr; >- >- // Set up a corresponding scale factor on the graphics context. >- buffer->context().scale(scaledSize / size); >- return buffer; >-} >- >-std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const GraphicsContext& context) >-{ >-#if USE(DIRECT2D) >- return create(size, context.renderingMode(), &context, resolutionScale, colorSpace); >-#else >- return create(size, context.renderingMode(), resolutionScale, colorSpace); >-#endif >+ return imageBuffer->sinkIntoNativeImage(); > } > >-IntSize ImageBuffer::compatibleBufferSize(const FloatSize& size, const GraphicsContext& context) >+RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, PreserveResolution preserveResolution) > { >- // Enlarge the buffer size if the context's transform is scaling it so we need a higher >- // resolution than one pixel per unit. >- return expandedIntSize(size * context.scaleFactor()); >+ return imageBuffer->sinkIntoImage(preserveResolution); > } > >-#if !USE(IOSURFACE_CANVAS_BACKING_STORE) >-size_t ImageBuffer::memoryCost() const >+void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) > { >- // memoryCost() may be invoked concurrently from a GC thread, and we need to be careful about what data we access here and how. >- // It's safe to access internalSize() because it doesn't do any pointer chasing. >- return 4 * internalSize().width() * internalSize().height(); >+ imageBuffer->drawConsuming(context, destRect, srcRect, options); > } > >-size_t ImageBuffer::externalMemoryCost() const >-{ >- return 0; >-} >-#endif >- >-} >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h >index 7b772a2f2d8f6e7577eafc6db229306b7cfedf9b..3551f45f82beba37f2971a09507d2b5f2f52d59a 100644 >--- a/Source/WebCore/platform/graphics/ImageBuffer.h >+++ b/Source/WebCore/platform/graphics/ImageBuffer.h >@@ -1,6 +1,6 @@ > /* > * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >- * Copyright (C) 2007-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2007-2020 Apple Inc. All rights reserved. > * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without >@@ -27,160 +27,83 @@ > > #pragma once > >-#include "AffineTransform.h" >-#include "AlphaPremultiplication.h" >-#include "ColorSpace.h" >-#include "GraphicsTypes.h" >-#include "GraphicsTypesGL.h" >-#include "ImageBufferData.h" >-#include "ImagePaintingOptions.h" >-#include "IntSize.h" >-#include "PlatformLayer.h" >+#include "ImageBufferBackend.h" > #include "RenderingMode.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >-#include <memory> >-#include <wtf/Forward.h> >-#include <wtf/IsoMalloc.h> >-#include <wtf/RefPtr.h> >-#include <wtf/Vector.h> > > namespace WebCore { > >-class FloatRect; >-class GraphicsContext; >-class GraphicsContextGLOpenGL; >-class Image; >-class ImageData; >-class IntPoint; >-class IntRect; >-class HostWindow; >- >-enum BackingStoreCopy { >- CopyBackingStore, // Guarantee subsequent draws don't affect the copy. >- DontCopyBackingStore // Subsequent draws may affect the copy. >-}; >- >-enum class PreserveResolution { >- No, >- Yes, >-}; >+namespace DisplayList { >+class DrawingContext; >+} > > class ImageBuffer { >- WTF_MAKE_ISO_ALLOCATED_EXPORT(ImageBuffer, WEBCORE_EXPORT); >- WTF_MAKE_NONCOPYABLE(ImageBuffer); >- friend class IOSurface; > public: >- // Will return a null pointer on allocation failure. > WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, float resolutionScale = 1, ColorSpace = ColorSpace::SRGB, const HostWindow* = nullptr); >-#if USE(DIRECT2D) >- WEBCORE_EXPORT static std::unique_ptr<ImageBuffer> create(const FloatSize&, RenderingMode, const GraphicsContext*, float resolutionScale = 1, ColorSpace = ColorSpace::SRGB, const HostWindow* = nullptr); >-#endif >- >- // Create an image buffer compatible with the context and copy rect from this buffer into this new one. >- std::unique_ptr<ImageBuffer> copyRectToBuffer(const FloatRect&, ColorSpace, const GraphicsContext&); >+ static std::unique_ptr<ImageBuffer> create(const FloatSize&, const GraphicsContext&); > > // Create an image buffer compatible with the context, with suitable resolution for drawing into the buffer and then into this context. > static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, const GraphicsContext&); > static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, ColorSpace, const GraphicsContext&); > static std::unique_ptr<ImageBuffer> createCompatibleBuffer(const FloatSize&, float resolutionScale, ColorSpace, const GraphicsContext&); > >- static IntSize compatibleBufferSize(const FloatSize&, const GraphicsContext&); >+ // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper. >+ static bool sizeNeedsClamping(const FloatSize&); >+ static bool sizeNeedsClamping(const FloatSize&, FloatSize& scale); >+ static FloatSize clampedSize(const FloatSize&); >+ static FloatSize clampedSize(const FloatSize&, FloatSize& scale); >+ static FloatRect clampedRect(const FloatRect&); > >- WEBCORE_EXPORT ~ImageBuffer(); >+ static IntSize compatibleBufferSize(const FloatSize&, const GraphicsContext&); >+ >+ WEBCORE_EXPORT virtual ~ImageBuffer() = default; > >- // The actual resolution of the backing store >- const IntSize& internalSize() const { return m_size; } >- const IntSize& logicalSize() const { return m_logicalSize; } >- float resolutionScale() const { return m_resolutionScale; } >+ virtual GraphicsContext& context() const = 0; >+ virtual void flushContext() = 0; > >- WEBCORE_EXPORT GraphicsContext& context() const; >+ virtual DisplayList::DrawingContext* drawingContext() { return nullptr; } >+ virtual void flushDrawingContext() { } > >- WEBCORE_EXPORT RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const; >- WEBCORE_EXPORT static RefPtr<Image> sinkIntoImage(std::unique_ptr<ImageBuffer>, PreserveResolution = PreserveResolution::No); >+ virtual AffineTransform baseTransform() const = 0; >+ virtual IntSize logicalSize() const = 0; >+ virtual IntSize backendSize() const = 0; >+ virtual float resolutionScale() const = 0; >+ >+ virtual size_t memoryCost() const = 0; >+ virtual size_t externalMemoryCost() const = 0; > >- enum CoordinateSystem { LogicalCoordinateSystem, BackingStoreCoordinateSystem }; >+ virtual NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const = 0; >+ virtual RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const = 0; > >- RefPtr<Uint8ClampedArray> getUnmultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const; >- RefPtr<Uint8ClampedArray> getPremultipliedImageData(const IntRect&, IntSize* pixelArrayDimensions = nullptr, CoordinateSystem = LogicalCoordinateSystem) const; >+ std::unique_ptr<ImageBuffer> copyRectToBuffer(const FloatRect&, ColorSpace, const GraphicsContext&); > >- void putByteArray(const Uint8ClampedArray&, AlphaPremultiplication bufferFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem = LogicalCoordinateSystem); >- >- void convertToLuminanceMask(); >+ virtual void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { }) = 0; >+ virtual void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }) = 0; > >- String toDataURL(const String& mimeType, Optional<double> quality = WTF::nullopt, PreserveResolution = PreserveResolution::No) const; >- Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const; >- Vector<uint8_t> toBGRAData() const; >+ static NativeImagePtr sinkIntoNativeImage(std::unique_ptr<ImageBuffer>); >+ WEBCORE_EXPORT static RefPtr<Image> sinkIntoImage(std::unique_ptr<ImageBuffer>, PreserveResolution = PreserveResolution::No); >+ static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { }); > >-#if USE(CAIRO) >- NativeImagePtr nativeImage() const; >-#endif >+ virtual void convertToLuminanceMask() = 0; >+ virtual void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace) = 0; > >-#if !USE(CG) >- AffineTransform baseTransform() const { return AffineTransform(); } >- void transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace); >- void platformTransformColorSpace(const std::array<uint8_t, 256>&); >-#else >- AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_data.backingStoreSize.height()); } >-#endif >- PlatformLayer* platformLayer() const; >+ virtual String toDataURL(const String& mimeType, Optional<double> quality = WTF::nullopt, PreserveResolution = PreserveResolution::No) const = 0; >+ virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality = WTF::nullopt) const = 0; >+ virtual Vector<uint8_t> toBGRAData() const = 0; > >- size_t memoryCost() const; >- size_t externalMemoryCost() const; >+ virtual RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const = 0; >+ virtual void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint = { }) = 0; > > // FIXME: current implementations of this method have the restriction that they only work > // with textures that are RGB or RGBA format, and UNSIGNED_BYTE type. >- bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool); >+ virtual bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const = 0; >+ virtual PlatformLayer* platformLayer() const = 0; > >- // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper. >- static bool sizeNeedsClamping(const FloatSize&); >- static bool sizeNeedsClamping(const FloatSize&, FloatSize& scale); >- static FloatSize clampedSize(const FloatSize&); >- static FloatSize clampedSize(const FloatSize&, FloatSize& scale); >- static FloatRect clampedRect(const FloatRect&); >- >-private: >-#if USE(CG) >- // The returned image might be larger than the internalSize(). If you want the smaller >- // image, crop the result. >- RetainPtr<CGImageRef> copyNativeImage(BackingStoreCopy = CopyBackingStore) const; >- static RetainPtr<CGImageRef> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>); >- void flushContext() const; >-#elif USE(DIRECT2D) >- COMPtr<ID2D1Bitmap> copyNativeImage(BackingStoreCopy = CopyBackingStore) const; >- static COMPtr<ID2D1Bitmap> sinkIntoNativeImage(std::unique_ptr<ImageBuffer>); >- void flushContext() const; >-#endif >+protected: >+ ImageBuffer() = default; > >- void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { }); >- void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& = { }); >- >- static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), const ImagePaintingOptions& = { }); >- >- inline void genericConvertToLuminanceMask(); >- >- friend class GraphicsContext; >- friend class GeneratedImage; >- friend class CrossfadeGeneratedImage; >- friend class NamedImageGeneratedImage; >- friend class GradientImage; >- friend class CustomPaintImage; >- friend class BitmapImage; >- >-private: >- ImageBufferData m_data; >- IntSize m_size; >- IntSize m_logicalSize; >- float m_resolutionScale; >- >- // This constructor will place its success into the given out-variable >- // so that create() knows when it should return failure. >- WEBCORE_EXPORT ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, const HostWindow*, bool& success); >-#if USE(CG) >- ImageBuffer(const FloatSize&, float resolutionScale, CGColorSpaceRef, RenderingMode, const HostWindow*, bool& success); >- RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const; >-#elif USE(DIRECT2D) >- ImageBuffer(const FloatSize&, float resolutionScale, ColorSpace, RenderingMode, const HostWindow*, const GraphicsContext*, bool& success); >-#endif >+ virtual NativeImagePtr sinkIntoNativeImage() = 0; >+ virtual RefPtr<Image> sinkIntoImage(PreserveResolution = PreserveResolution::No) = 0; >+ virtual void drawConsuming(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) = 0; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/ImageBufferBackend.cpp b/Source/WebCore/platform/graphics/ImageBufferBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..463aa5da626253b51d92fed81abcabd2743dee86 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/ImageBufferBackend.cpp >@@ -0,0 +1,274 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferBackend.h" >+ >+#include "Image.h" >+#include "ImageData.h" >+ >+namespace WebCore { >+ >+ImageBufferBackend::ImageBufferBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace) >+ : m_logicalSize(logicalSize) >+ , m_backendSize(backendSize) >+ , m_resolutionScale(resolutionScale) >+ , m_colorSpace(colorSpace) >+{ >+} >+ >+IntSize ImageBufferBackend::calculateBackendSize(const FloatSize& size, float resolutionScale) >+{ >+ FloatSize scaledSize = { ceilf(resolutionScale * size.width()), ceilf(resolutionScale * size.height()) }; >+ if (scaledSize.isEmpty() || !scaledSize.isExpressibleAsIntSize()) >+ return { }; >+ >+ IntSize backendSize = IntSize(scaledSize); >+ >+ Checked<unsigned, RecordOverflow> bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(backendSize.width()); >+ if (bytesPerRow.hasOverflowed()) >+ return { }; >+ >+ Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(backendSize.height()) * bytesPerRow; >+ if (numBytes.hasOverflowed()) >+ return { }; >+ >+ return backendSize; >+} >+ >+NativeImagePtr ImageBufferBackend::sinkIntoNativeImage() >+{ >+ return copyNativeImage(DontCopyBackingStore); >+} >+ >+RefPtr<Image> ImageBufferBackend::sinkIntoImage(PreserveResolution preserveResolution) >+{ >+ return copyImage(DontCopyBackingStore, preserveResolution); >+} >+ >+void ImageBufferBackend::drawConsuming(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >+{ >+ draw(destContext, destRect, srcRect, options); >+} >+ >+void ImageBufferBackend::convertToLuminanceMask() >+{ >+ auto imageData = getImageData(AlphaPremultiplication::Unpremultiplied, logicalRect()); >+ if (!imageData) >+ return; >+ >+ auto* srcPixelArray = imageData->data(); >+ unsigned pixelArrayLength = srcPixelArray->length(); >+ for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { >+ uint8_t a = srcPixelArray->item(pixelOffset + 3); >+ if (!a) >+ continue; >+ uint8_t r = srcPixelArray->item(pixelOffset); >+ uint8_t g = srcPixelArray->item(pixelOffset + 1); >+ uint8_t b = srcPixelArray->item(pixelOffset + 2); >+ >+ double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); >+ srcPixelArray->set(pixelOffset + 3, luma); >+ } >+ >+ putImageData(AlphaPremultiplication::Unpremultiplied, *imageData, logicalRect(), IntPoint::zero()); >+} >+ >+Vector<uint8_t> ImageBufferBackend::toBGRAData(void* data) const >+{ >+ Vector<uint8_t> result(4 * m_logicalSize.area().unsafeGet()); >+ size_t destBytesPerRow = m_logicalSize.width() * 4; >+ size_t srcBytesPerRow = bytesPerRow(); >+ >+ uint8_t* srcRows = reinterpret_cast<uint8_t*>(data); >+ >+ copyImagePixels( >+ AlphaPremultiplication::Premultiplied, backendColorFormat(), srcBytesPerRow, srcRows, >+ AlphaPremultiplication::Unpremultiplied, ColorFormat::BGRA, destBytesPerRow, result.data(), m_logicalSize); >+ >+ return result; >+} >+ >+static inline void copyPremultipliedToPremultiplied(ColorFormat srcColorFormat, const uint8_t* srcPixel, ColorFormat destColorFormat, uint8_t* destPixel) >+{ >+ uint8_t alpha = srcPixel[3]; >+ if (!alpha) { >+ reinterpret_cast<uint32_t*>(destPixel)[0] = 0; >+ return; >+ } >+ >+ if (srcColorFormat == destColorFormat) { >+ reinterpret_cast<uint32_t*>(destPixel)[0] = reinterpret_cast<const uint32_t*>(srcPixel)[0]; >+ return; >+ } >+ >+ // Swap pixel channels BGRA <-> RGBA. >+ destPixel[0] = srcPixel[2]; >+ destPixel[1] = srcPixel[1]; >+ destPixel[2] = srcPixel[0]; >+ destPixel[3] = srcPixel[3]; >+} >+ >+static inline void copyPremultipliedToUnpremultiplied(ColorFormat srcColorFormat, const uint8_t* srcPixel, ColorFormat destColorFormat, uint8_t* destPixel) >+{ >+ uint8_t alpha = srcPixel[3]; >+ if (!alpha || alpha == 255) { >+ copyPremultipliedToPremultiplied(srcColorFormat, srcPixel, destColorFormat, destPixel); >+ return; >+ } >+ >+ if (srcColorFormat == destColorFormat) { >+ destPixel[0] = (srcPixel[0] * 255) / alpha; >+ destPixel[1] = (srcPixel[1] * 255) / alpha; >+ destPixel[2] = (srcPixel[2] * 255) / alpha; >+ destPixel[3] = alpha; >+ return; >+ } >+ >+ // Swap pixel channels BGRA <-> RGBA. >+ destPixel[0] = (srcPixel[2] * 255) / alpha; >+ destPixel[1] = (srcPixel[1] * 255) / alpha; >+ destPixel[2] = (srcPixel[0] * 255) / alpha; >+ destPixel[3] = alpha; >+} >+ >+static inline void copyUnpremultipliedToPremultiplied(ColorFormat srcColorFormat, const uint8_t* srcPixel, ColorFormat destColorFormat, uint8_t* destPixel) >+{ >+ uint8_t alpha = srcPixel[3]; >+ if (!alpha || alpha == 255) { >+ copyPremultipliedToPremultiplied(srcColorFormat, srcPixel, destColorFormat, destPixel); >+ return; >+ } >+ >+ if (srcColorFormat == destColorFormat) { >+ destPixel[0] = (srcPixel[0] * alpha + 254) / 255; >+ destPixel[1] = (srcPixel[1] * alpha + 254) / 255; >+ destPixel[2] = (srcPixel[2] * alpha + 254) / 255; >+ destPixel[3] = alpha; >+ return; >+ } >+ >+ // Swap pixel channels BGRA <-> RGBA. >+ destPixel[0] = (srcPixel[2] * alpha + 254) / 255; >+ destPixel[1] = (srcPixel[1] * alpha + 254) / 255; >+ destPixel[2] = (srcPixel[0] * alpha + 254) / 255; >+ destPixel[3] = alpha; >+} >+ >+template<void (*copyFunctor)(ColorFormat, const uint8_t*, ColorFormat, uint8_t*)> >+static inline void copyImagePixelsUnaccelerated( >+ ColorFormat srcColorFormat, unsigned srcBytesPerRow, uint8_t* srcRows, >+ ColorFormat destColorFormat, unsigned destBytesPerRow, uint8_t* destRows, const IntSize& size) >+{ >+ size_t bytesPerRow = size.width() * 4; >+ for (int y = 0; y < size.height(); ++y) { >+ for (size_t x = 0; x < bytesPerRow; x += 4) >+ copyFunctor(srcColorFormat, &srcRows[x], destColorFormat, &destRows[x]); >+ srcRows += srcBytesPerRow; >+ destRows += destBytesPerRow; >+ } >+} >+ >+void ImageBufferBackend::copyImagePixels( >+ AlphaPremultiplication srcAlphaFormat, ColorFormat srcColorFormat, unsigned srcBytesPerRow, uint8_t* srcRows, >+ AlphaPremultiplication destAlphaFormat, ColorFormat destColorFormat, unsigned destBytesPerRow, uint8_t* destRows, const IntSize& size) const >+{ >+ if (srcAlphaFormat == destAlphaFormat) { >+ ASSERT(srcAlphaFormat == AlphaPremultiplication::Premultiplied && destAlphaFormat == AlphaPremultiplication::Premultiplied); >+ copyImagePixelsUnaccelerated<copyPremultipliedToPremultiplied>(srcColorFormat, srcBytesPerRow, srcRows, destColorFormat, destBytesPerRow, destRows, size); >+ return; >+ } >+ >+ if (destAlphaFormat == AlphaPremultiplication::Unpremultiplied) { >+ copyImagePixelsUnaccelerated<copyPremultipliedToUnpremultiplied>(srcColorFormat, srcBytesPerRow, srcRows, destColorFormat, destBytesPerRow, destRows, size); >+ return; >+ } >+ >+ copyImagePixelsUnaccelerated<copyUnpremultipliedToPremultiplied>(srcColorFormat, srcBytesPerRow, srcRows, destColorFormat, destBytesPerRow, destRows, size); >+} >+ >+RefPtr<ImageData> ImageBufferBackend::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect, void* data) const >+{ >+ IntRect srcRectScaled = toBackendCoordinates(srcRect); >+ >+ auto imageData = ImageData::create(srcRectScaled.size()); >+ if (!imageData || !imageData->data()) >+ return nullptr; >+ >+ IntRect srcRectClipped = intersection(backendRect(), srcRectScaled); >+ IntRect destRect = { IntPoint::zero(), srcRectClipped.size() }; >+ >+ if (srcRectScaled.x() < 0) >+ destRect.setX(-srcRectScaled.x()); >+ >+ if (srcRectScaled.y() < 0) >+ destRect.setY(-srcRectScaled.y()); >+ >+ if (destRect.size() != srcRectScaled.size()) >+ imageData->data()->zeroFill(); >+ >+ unsigned destBytesPerRow = 4 * srcRectScaled.width(); >+ uint8_t* destRows = imageData->data()->data() + destRect.y() * destBytesPerRow + destRect.x() * 4; >+ >+ unsigned srcBytesPerRow = bytesPerRow(); >+ uint8_t* srcRows = reinterpret_cast<uint8_t*>(data) + srcRectClipped.y() * srcBytesPerRow + srcRectClipped.x() * 4; >+ >+ copyImagePixels( >+ AlphaPremultiplication::Premultiplied, backendColorFormat(), srcBytesPerRow, srcRows, >+ outputFormat, ColorFormat::RGBA, destBytesPerRow, destRows, destRect.size()); >+ >+ return imageData; >+} >+ >+void ImageBufferBackend::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint, void* data) >+{ >+ IntRect srcRectScaled = toBackendCoordinates(srcRect); >+ IntPoint destPointScaled = toBackendCoordinates(destPoint); >+ >+ IntRect srcRectClipped = intersection({ IntPoint::zero(), imageData.size() }, srcRectScaled); >+ IntRect destRect = srcRectClipped; >+ destRect.moveBy(destPointScaled); >+ >+ if (srcRectScaled.x() < 0) >+ destRect.setX(destRect.x() - srcRectScaled.x()); >+ >+ if (srcRectScaled.y() < 0) >+ destRect.setY(destRect.y() - srcRectScaled.y()); >+ >+ destRect.intersect(backendRect()); >+ srcRectClipped.setSize(destRect.size()); >+ >+ unsigned destBytesPerRow = bytesPerRow(); >+ uint8_t* destRows = reinterpret_cast<uint8_t*>(data) + destRect.y() * destBytesPerRow + destRect.x() * 4; >+ >+ unsigned srcBytesPerRow = 4 * imageData.size().width(); >+ uint8_t* srcRows = imageData.data()->data() + srcRectClipped.y() * srcBytesPerRow + srcRectClipped.x() * 4; >+ >+ copyImagePixels( >+ inputFormat, ColorFormat::RGBA, srcBytesPerRow, srcRows, >+ AlphaPremultiplication::Premultiplied, backendColorFormat(), destBytesPerRow, destRows, destRect.size()); >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/ImageBufferBackend.h b/Source/WebCore/platform/graphics/ImageBufferBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9a3b63cdf7178abb1b5a38829c55e128edb7a24a >--- /dev/null >+++ b/Source/WebCore/platform/graphics/ImageBufferBackend.h >@@ -0,0 +1,135 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "AlphaPremultiplication.h" >+#include "ColorSpace.h" >+#include "FloatRect.h" >+#include "GraphicsTypesGL.h" >+#include "ImagePaintingOptions.h" >+#include "IntRect.h" >+#include "NativeImage.h" >+#include "PlatformLayer.h" >+#include <wtf/RefPtr.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+class GraphicsContextGLOpenGL; >+class HostWindow; >+class Image; >+class ImageData; >+ >+enum BackingStoreCopy { >+ CopyBackingStore, // Guarantee subsequent draws don't affect the copy. >+ DontCopyBackingStore // Subsequent draws may affect the copy. >+}; >+ >+enum class PreserveResolution : uint8_t { >+ No, >+ Yes, >+}; >+ >+enum class ColorFormat : uint8_t { >+ RGBA, >+ BGRA >+}; >+ >+class ImageBufferBackend { >+public: >+ WEBCORE_EXPORT virtual ~ImageBufferBackend() = default; >+ >+ WEBCORE_EXPORT static IntSize calculateBackendSize(const FloatSize&, float resolutionScale); >+ >+ virtual GraphicsContext& context() const = 0; >+ virtual void flushContext() { } >+ >+ IntSize logicalSize() const { return m_logicalSize; } >+ IntSize backendSize() const { return m_backendSize; } >+ float resolutionScale() const { return m_resolutionScale; } >+ ColorSpace colorSpace() const { return m_colorSpace; } >+ >+ virtual AffineTransform baseTransform() const { return AffineTransform(); } >+ virtual size_t memoryCost() const { return 4 * m_backendSize.area().unsafeGet(); } >+ virtual size_t externalMemoryCost() const { return 0; } >+ >+ virtual NativeImagePtr copyNativeImage(BackingStoreCopy) const = 0; >+ virtual RefPtr<Image> copyImage(BackingStoreCopy, PreserveResolution) const = 0; >+ >+ WEBCORE_EXPORT virtual void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) = 0; >+ WEBCORE_EXPORT virtual void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions&) = 0; >+ >+ WEBCORE_EXPORT virtual NativeImagePtr sinkIntoNativeImage(); >+ WEBCORE_EXPORT virtual RefPtr<Image> sinkIntoImage(PreserveResolution); >+ WEBCORE_EXPORT virtual void drawConsuming(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&); >+ >+ WEBCORE_EXPORT void convertToLuminanceMask(); >+ virtual void transformColorSpace(ColorSpace, ColorSpace) { } >+ >+ virtual String toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const = 0; >+ virtual Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const = 0; >+ virtual Vector<uint8_t> toBGRAData() const = 0; >+ >+ virtual RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect&) const = 0; >+ virtual void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint) = 0; >+ >+ virtual PlatformLayer* platformLayer() const { return nullptr; } >+ virtual bool copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum, PlatformGLObject, GCGLenum, bool, bool) const { return false; } >+ >+protected: >+ WEBCORE_EXPORT ImageBufferBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace); >+ >+ virtual unsigned bytesPerRow() const { return 4 * m_backendSize.width(); } >+ virtual ColorFormat backendColorFormat() const { return ColorFormat::RGBA; } >+ >+ template<typename T> >+ T toBackendCoordinates(T t) const >+ { >+ static_assert(std::is_same<T, IntPoint>::value || std::is_same<T, IntSize>::value || std::is_same<T, IntRect>::value); >+ if (m_resolutionScale != 1) >+ t.scale(m_resolutionScale); >+ return t; >+ } >+ >+ IntRect logicalRect() const { return IntRect(IntPoint::zero(), m_logicalSize); }; >+ IntRect backendRect() const { return IntRect(IntPoint::zero(), m_backendSize); }; >+ >+ WEBCORE_EXPORT virtual void copyImagePixels( >+ AlphaPremultiplication srcAlphaFormat, ColorFormat srcColorFormat, unsigned srcBytesPerRow, uint8_t* srcRows, >+ AlphaPremultiplication destAlphaFormat, ColorFormat destColorFormat, unsigned destBytesPerRow, uint8_t* destRows, const IntSize&) const; >+ >+ WEBCORE_EXPORT Vector<uint8_t> toBGRAData(void* data) const; >+ >+ WEBCORE_EXPORT RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect, void* data) const; >+ WEBCORE_EXPORT void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint, void* data); >+ >+ IntSize m_logicalSize; >+ IntSize m_backendSize; >+ float m_resolutionScale; >+ ColorSpace m_colorSpace; >+}; >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/ImageBufferData.h b/Source/WebCore/platform/graphics/ImageBufferData.h >deleted file mode 100644 >index 642a5c885e5c102447c73a12f1d6fb32b5d39903..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/ImageBufferData.h >+++ /dev/null >@@ -1,34 +0,0 @@ >-/* >- * Copyright (C) 2011-2020 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#if USE(CG) >-#include "ImageBufferDataCG.h" >-#elif USE(DIRECT2D) >-#include "ImageBufferDataDirect2D.h" >-#elif USE(CAIRO) >-#include "ImageBufferDataCairo.h" >-#endif >diff --git a/Source/WebCore/platform/graphics/PlatformImageBuffer.h b/Source/WebCore/platform/graphics/PlatformImageBuffer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b43a8719ce49d1776b9753d5d7260877f0514360 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/PlatformImageBuffer.h >@@ -0,0 +1,68 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ContextualImageBuffer.h" >+#include "DisplayListImageBuffer.h" >+ >+#if USE(CG) >+#include "ImageBufferCGBitmapBackend.h" >+#elif USE(DIRECT2D) >+#include "ImageBufferDirect2DBackend.h" >+#elif USE(CAIRO) >+#include "ImageBufferCairoImageSurfaceBackend.h" >+#endif >+ >+#if HAVE(IOSURFACE) >+#include "ImageBufferIOSurfaceBackend.h" >+#elif USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS) >+#include "ImageBufferCairoGLSurfaceBackend.h" >+#endif >+ >+namespace WebCore { >+ >+#if USE(CG) >+using PlatformUnacceleratedImageBufferBackend = ImageBufferCGBitmapBackend; >+#elif USE(DIRECT2D) >+using PlatformUnacceleratedImageBufferBackend = ImageBufferDirect2DBackend; >+#elif USE(CAIRO) >+using PlatformUnacceleratedImageBufferBackend = ImageBufferCairoImageSurfaceBackend; >+#endif >+ >+#if HAVE(IOSURFACE) >+using PlatformAcceleratedImageBufferBackend = ImageBufferIOSurfaceBackend; >+#elif USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS) >+using PlatformAcceleratedImageBufferBackend = ImageBufferCairoGLSurfaceBackend; >+#else >+using PlatformAcceleratedImageBufferBackend = PlatformUnacceleratedImageBufferBackend; >+#endif >+ >+using PlatformImageBuffer = ContextualImageBuffer<PlatformUnacceleratedImageBufferBackend>; >+using PlatformAcceleratedImageBuffer = ContextualImageBuffer<PlatformAcceleratedImageBufferBackend>; >+using PlatformDisplayListImageBuffer = DisplayListImageBuffer<PlatformUnacceleratedImageBufferBackend>; >+using PlatformAcceleratedDisplayListImageBuffer = DisplayListImageBuffer<PlatformAcceleratedImageBufferBackend>; >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/RenderingBackend.cpp b/Source/WebCore/platform/graphics/RenderingBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..03cb6b241aa5d105f3cac8edc239d0f51fba933c >--- /dev/null >+++ b/Source/WebCore/platform/graphics/RenderingBackend.cpp >@@ -0,0 +1,104 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RenderingBackend.h" >+ >+#include "Chrome.h" >+#include "ChromeClient.h" >+#include "GraphicsContext.h" >+#include "Page.h" >+#include "PlatformImageBuffer.h" >+ >+namespace WebCore { >+ >+std::unique_ptr<RenderingBackend> RenderingBackend::create() >+{ >+ return std::unique_ptr<RenderingBackend>(new RenderingBackend()); >+} >+ >+RenderingBackend& RenderingBackend::sharedRenderingBackend(const HostWindow* hostWindow) >+{ >+ static NeverDestroyed<std::unique_ptr<RenderingBackend>> sharedRenderingBackend { RenderingBackend::create() }; >+ return hostWindow && hostWindow->sharedRenderingBackend() ? *hostWindow->sharedRenderingBackend() : *sharedRenderingBackend.get(); >+} >+ >+std::unique_ptr<ImageBuffer> RenderingBackend::createImageBuffer(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+{ >+ std::unique_ptr<ImageBuffer> imageBuffer; >+ >+ switch (renderingMode) { >+ case RenderingMode::Accelerated: >+ case RenderingMode::RemoteAccelerated: >+ imageBuffer = PlatformAcceleratedImageBuffer::create(size, resolutionScale, colorSpace, hostWindow); >+ FALLTHROUGH; >+ case RenderingMode::Unaccelerated: >+ case RenderingMode::Remote: >+ if (!imageBuffer) >+ imageBuffer = PlatformImageBuffer::create(size, resolutionScale, colorSpace, hostWindow); >+ break; >+ >+ case RenderingMode::DisplayListAccelerated: >+ imageBuffer = PlatformAcceleratedDisplayListImageBuffer::create(size, resolutionScale, colorSpace, hostWindow); >+ FALLTHROUGH; >+ case RenderingMode::DisplayList: >+ if (!imageBuffer) >+ imageBuffer = PlatformDisplayListImageBuffer::create(size, resolutionScale, colorSpace, hostWindow); >+ break; >+ } >+ >+ return imageBuffer; >+} >+ >+std::unique_ptr<ImageBuffer> RenderingBackend::createImageBuffer(const FloatSize& size, const GraphicsContext& context) >+{ >+ std::unique_ptr<ImageBuffer> imageBuffer; >+ >+ switch (context.renderingMode()) { >+ case RenderingMode::Accelerated: >+ case RenderingMode::RemoteAccelerated: >+ imageBuffer = PlatformAcceleratedImageBuffer::create(size, context); >+ FALLTHROUGH; >+ case RenderingMode::Unaccelerated: >+ case RenderingMode::Remote: >+ if (!imageBuffer) >+ imageBuffer = PlatformImageBuffer::create(size, context); >+ break; >+ >+ case RenderingMode::DisplayListAccelerated: >+ imageBuffer = PlatformAcceleratedDisplayListImageBuffer::create(size, context); >+ FALLTHROUGH; >+ case RenderingMode::DisplayList: >+ if (!imageBuffer) >+ imageBuffer = PlatformDisplayListImageBuffer::create(size, context); >+ break; >+ } >+ >+ return imageBuffer; >+} >+ >+} // namespace WebCore >+ >+ >diff --git a/Source/WebCore/platform/graphics/RenderingBackend.h b/Source/WebCore/platform/graphics/RenderingBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..fac73068575d201e1c01f7c00a380cf61ae52839 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/RenderingBackend.h >@@ -0,0 +1,53 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ColorSpace.h" >+#include "FloatSize.h" >+#include "RenderingMode.h" >+ >+namespace WebCore { >+ >+class GraphicsContext; >+class HostWindow; >+class ImageBuffer; >+class IntSize; >+ >+class WEBCORE_EXPORT RenderingBackend { >+public: >+ static std::unique_ptr<RenderingBackend> create(); >+ >+ static RenderingBackend& sharedRenderingBackend(const HostWindow* = nullptr); >+ >+ virtual ~RenderingBackend() = default; >+ virtual std::unique_ptr<ImageBuffer> createImageBuffer(const FloatSize&, RenderingMode, float resolutionScale, ColorSpace, const HostWindow*); >+ virtual std::unique_ptr<ImageBuffer> createImageBuffer(const FloatSize&, const GraphicsContext&); >+ >+protected: >+ RenderingBackend() = default; >+}; >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/RenderingMode.h b/Source/WebCore/platform/graphics/RenderingMode.h >index 69d8ae81c848b10e6f2d07a789b16c333dc23cb4..aa4835dbfaaaa9742f34acc38f8a1e0e270c24e0 100644 >--- a/Source/WebCore/platform/graphics/RenderingMode.h >+++ b/Source/WebCore/platform/graphics/RenderingMode.h >@@ -30,6 +30,10 @@ namespace WebCore { > enum class RenderingMode : uint8_t { > Accelerated, > Unaccelerated, >+ DisplayListAccelerated, >+ DisplayList, >+ RemoteAccelerated, >+ Remote > }; > > } // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/ShadowBlur.cpp b/Source/WebCore/platform/graphics/ShadowBlur.cpp >index 681ab56eeb3419462b234450d00f41f933674d18..3cfce72954209d303a9f72432fbb4b639d4b4213 100644 >--- a/Source/WebCore/platform/graphics/ShadowBlur.cpp >+++ b/Source/WebCore/platform/graphics/ShadowBlur.cpp >@@ -34,6 +34,7 @@ > #include "FloatQuad.h" > #include "GraphicsContext.h" > #include "ImageBuffer.h" >+#include "ImageData.h" > #include "Timer.h" > #include <wtf/MathExtras.h> > #include <wtf/NeverDestroyed.h> >@@ -449,7 +450,7 @@ void ShadowBlur::drawShadowBuffer(GraphicsContext& graphicsContext, ImageBuffer& > { > GraphicsContextStateSaver stateSaver(graphicsContext); > >- IntSize bufferSize = layerImage.internalSize(); >+ IntSize bufferSize = layerImage.backendSize(); > if (bufferSize != layerSize) { > // The rect passed to clipToImageBuffer() has to be the size of the entire buffer, > // but we may not have cleared it all, so clip to the filled part first. >@@ -884,12 +885,13 @@ void ShadowBlur::blurShadowBuffer(ImageBuffer& layerImage, const IntSize& templa > return; > > IntRect blurRect(IntPoint(), templateSize); >- auto layerData = layerImage.getUnmultipliedImageData(blurRect); >+ auto layerData = layerImage.getImageData(AlphaPremultiplication::Unpremultiplied, blurRect); > if (!layerData) > return; > >- blurLayerImage(layerData->data(), blurRect.size(), blurRect.width() * 4); >- layerImage.putByteArray(*layerData, AlphaPremultiplication::Unpremultiplied, blurRect.size(), blurRect, { }); >+ auto* blurPixelArray = layerData->data(); >+ blurLayerImage(blurPixelArray->data(), blurRect.size(), blurRect.width() * 4); >+ layerImage.putImageData(AlphaPremultiplication::Unpremultiplied, *layerData, blurRect); > } > > void ShadowBlur::blurAndColorShadowBuffer(ImageBuffer& layerImage, const IntSize& templateSize) >diff --git a/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp b/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp >index 68984d564a92927d428fcebb80e14aacf9afa4ef..cd8f1db359e26a01a2c85bbd22ea368e6ac8894b 100644 >--- a/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp >+++ b/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp >@@ -175,7 +175,7 @@ enum PathDrawingStyle { > > static void drawShadowLayerBuffer(PlatformContextCairo& platformContext, ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const ShadowState& shadowState) > { >- if (auto surface = layerImage.nativeImage()) { >+ if (auto surface = layerImage.copyNativeImage(DontCopyBackingStore)) { > drawNativeImage(platformContext, surface.get(), FloatRect(roundedIntPoint(layerOrigin), layerSize), FloatRect(FloatPoint(), layerSize), { shadowState.globalCompositeOperator }, shadowState.globalAlpha, ShadowState()); > } > } >@@ -183,7 +183,7 @@ static void drawShadowLayerBuffer(PlatformContextCairo& platformContext, ImageBu > // FIXME: This is mostly same as drawShadowLayerBuffer, so we should merge two. > static void drawShadowImage(PlatformContextCairo& platformContext, ImageBuffer& layerImage, const FloatRect& destRect, const FloatRect& srcRect, const ShadowState& shadowState) > { >- if (auto surface = layerImage.nativeImage()) { >+ if (auto surface = layerImage.copyNativeImage(DontCopyBackingStore)) { > drawNativeImage(platformContext, surface.get(), destRect, srcRect, { shadowState.globalCompositeOperator }, shadowState.globalAlpha, ShadowState()); > } > } >@@ -192,7 +192,7 @@ static void fillShadowBuffer(PlatformContextCairo& platformContext, ImageBuffer& > { > save(platformContext); > >- if (auto surface = layerImage.nativeImage()) >+ if (auto surface = layerImage.copyNativeImage(DontCopyBackingStore)) > clipToImageBuffer(platformContext, surface.get(), FloatRect(layerOrigin, expandedIntSize(layerSize))); > > FillSource fillSource; >diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp >index 9b025e14767352e14ad48f867b04585ee8034134..4e1bf2b4367f34359d854eb78c2202df57b27478 100644 >--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp >+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp >@@ -268,7 +268,7 @@ void GraphicsContext::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& de > } > > ASSERT(hasPlatformContext()); >- if (auto surface = buffer.nativeImage()) >+ if (auto surface = buffer.copyNativeImage(DontCopyBackingStore)) > Cairo::clipToImageBuffer(*platformContext(), surface.get(), destRect); > } > >diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp >index bca29dfb694986e877466b8f07786fbd1bf39456..cd865aaa26019ffc75aeee926202cf112595bc81 100644 >--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp >+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp >@@ -414,7 +414,7 @@ IntRect GraphicsContextImplCairo::clipBounds() > > void GraphicsContextImplCairo::clipToImageBuffer(ImageBuffer& buffer, const FloatRect& destRect) > { >- if (auto surface = buffer.nativeImage()) >+ if (auto surface = buffer.copyNativeImage(DontCopyBackingStore)) > Cairo::clipToImageBuffer(m_platformContext, surface.get(), destRect); > } > >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp >deleted file mode 100644 >index bbb5c6482b6e1d3f28ac479ea7c5d31b1d337902..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp >+++ /dev/null >@@ -1,753 +0,0 @@ >-/* >- * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >- * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >- * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >- * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ImageBuffer.h" >- >-#if USE(CAIRO) >- >-#include "BitmapImage.h" >-#include "CairoOperations.h" >-#include "CairoUtilities.h" >-#include "Color.h" >-#include "GraphicsContext.h" >-#include "GraphicsContextImplCairo.h" >-#include "ImageBufferUtilitiesCairo.h" >-#include "MIMETypeRegistry.h" >-#include "NotImplemented.h" >-#include "Pattern.h" >-#include "PlatformContextCairo.h" >-#include "RefPtrCairo.h" >-#include <JavaScriptCore/JSCInlines.h> >-#include <JavaScriptCore/TypedArrayInlines.h> >-#include <cairo.h> >-#include <wtf/Vector.h> >-#include <wtf/text/Base64.h> >-#include <wtf/text/WTFString.h> >- >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#include "GLContext.h" >-#include "TextureMapperGL.h" >- >-#if USE(EGL) >-#if USE(LIBEPOXY) >-#include "EpoxyEGL.h" >-#else >-#include <EGL/egl.h> >-#endif >-#endif >-#include <cairo-gl.h> >- >-#if USE(LIBEPOXY) >-#include <epoxy/gl.h> >-#elif USE(OPENGL_ES) >-#include <GLES2/gl2.h> >-#else >-#include "OpenGLShims.h" >-#endif >- >-#if USE(COORDINATED_GRAPHICS) >-#include "TextureMapperPlatformLayerBuffer.h" >-#include "TextureMapperPlatformLayerProxy.h" >-#endif >-#endif >- >-namespace WebCore { >- >-ImageBufferData::ImageBufferData(const IntSize& size, RenderingMode renderingMode) >- : m_platformContext(0) >- , m_size(size) >- , m_renderingMode(renderingMode) >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#if USE(COORDINATED_GRAPHICS) >- , m_compositorTexture(0) >-#endif >- , m_texture(0) >-#endif >-{ >-#if ENABLE(ACCELERATED_2D_CANVAS) && USE(COORDINATED_GRAPHICS) >- if (m_renderingMode == RenderingMode::Accelerated) { >-#if USE(NICOSIA) >- m_nicosiaLayer = Nicosia::ContentLayer::create(Nicosia::ContentLayerTextureMapperImpl::createFactory(*this)); >-#else >- m_platformLayerProxy = adoptRef(new TextureMapperPlatformLayerProxy); >-#endif >- } >-#endif >-} >- >-ImageBufferData::~ImageBufferData() >-{ >- if (m_renderingMode != RenderingMode::Accelerated) >- return; >- >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#if USE(COORDINATED_GRAPHICS) && USE(NICOSIA) >- downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).invalidateClient(); >-#endif >- >- GLContext* previousActiveContext = GLContext::current(); >- PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent(); >- >- if (m_texture) >- glDeleteTextures(1, &m_texture); >- >-#if USE(COORDINATED_GRAPHICS) >- if (m_compositorTexture) >- glDeleteTextures(1, &m_compositorTexture); >-#endif >- >- if (previousActiveContext) >- previousActiveContext->makeContextCurrent(); >-#endif >-} >- >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#if USE(COORDINATED_GRAPHICS) >-void ImageBufferData::createCompositorBuffer() >-{ >- auto* context = PlatformDisplay::sharedDisplayForCompositing().sharingGLContext(); >- context->makeContextCurrent(); >- >- glGenTextures(1, &m_compositorTexture); >- glBindTexture(GL_TEXTURE_2D, m_compositorTexture); >- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); >- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); >- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); >- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); >- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); >- glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, m_size.width(), m_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); >- >- m_compositorSurface = adoptRef(cairo_gl_surface_create_for_texture(context->cairoDevice(), CAIRO_CONTENT_COLOR_ALPHA, m_compositorTexture, m_size.width(), m_size.height())); >- m_compositorCr = adoptRef(cairo_create(m_compositorSurface.get())); >- cairo_set_antialias(m_compositorCr.get(), CAIRO_ANTIALIAS_NONE); >-} >- >-#if !USE(NICOSIA) >-RefPtr<TextureMapperPlatformLayerProxy> ImageBufferData::proxy() const >-{ >- return m_platformLayerProxy.copyRef(); >-} >-#endif >- >-void ImageBufferData::swapBuffersIfNeeded() >-{ >- GLContext* previousActiveContext = GLContext::current(); >- >- if (!m_compositorTexture) { >- createCompositorBuffer(); >- >- auto proxyOperation = >- [this](TextureMapperPlatformLayerProxy& proxy) >- { >- LockHolder holder(proxy.lock()); >- proxy.pushNextBuffer(makeUnique<TextureMapperPlatformLayerBuffer>(m_compositorTexture, m_size, TextureMapperGL::ShouldBlend, GL_RGBA)); >- }; >-#if USE(NICOSIA) >- proxyOperation(downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).proxy()); >-#else >- proxyOperation(*m_platformLayerProxy); >-#endif >- } >- >- // It would be great if we could just swap the buffers here as we do with webgl, but that breaks the cases >- // where one frame uses the content already rendered in the previous frame. So we just copy the content >- // into the compositor buffer. >- cairo_set_source_surface(m_compositorCr.get(), m_surface.get(), 0, 0); >- cairo_set_operator(m_compositorCr.get(), CAIRO_OPERATOR_SOURCE); >- cairo_paint(m_compositorCr.get()); >- >- if (previousActiveContext) >- previousActiveContext->makeContextCurrent(); >-} >-#endif >- >-void clearSurface(cairo_surface_t* surface) >-{ >- if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) >- return; >- >- RefPtr<cairo_t> cr = adoptRef(cairo_create(surface)); >- cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR); >- cairo_paint(cr.get()); >-} >- >-void ImageBufferData::createCairoGLSurface() >-{ >- auto* context = PlatformDisplay::sharedDisplayForCompositing().sharingGLContext(); >- context->makeContextCurrent(); >- >- // We must generate the texture ourselves, because there is no Cairo API for extracting it >- // from a pre-existing surface. >- glGenTextures(1, &m_texture); >- glBindTexture(GL_TEXTURE_2D, m_texture); >- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); >- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); >- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); >- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); >- >- glPixelStorei(GL_UNPACK_ALIGNMENT, 1); >- >- glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, m_size.width(), m_size.height(), 0 /* border */, GL_RGBA, GL_UNSIGNED_BYTE, 0); >- >- cairo_device_t* device = context->cairoDevice(); >- >- // Thread-awareness is a huge performance hit on non-Intel drivers. >- cairo_gl_device_set_thread_aware(device, FALSE); >- >- m_surface = adoptRef(cairo_gl_surface_create_for_texture(device, CAIRO_CONTENT_COLOR_ALPHA, m_texture, m_size.width(), m_size.height())); >- clearSurface(m_surface.get()); >-} >-#endif >- >-static RefPtr<cairo_surface_t> >-cairoSurfaceCopy(cairo_surface_t* surface) >-{ >- auto copy = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, >- cairo_image_surface_get_width(surface), >- cairo_image_surface_get_height(surface))); >- >- auto cr = adoptRef(cairo_create(copy.get())); >- cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE); >- cairo_set_source_surface(cr.get(), surface, 0, 0); >- cairo_paint(cr.get()); >- >- return copy; >-} >- >-static RefPtr<cairo_surface_t> >-cairoSurfaceCoerceToImage(cairo_surface_t* surface) >-{ >- if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE >- && cairo_surface_get_content(surface) == CAIRO_CONTENT_COLOR_ALPHA) >- return surface; >- >- return cairoSurfaceCopy(surface); >-} >- >-Vector<uint8_t> ImageBuffer::toBGRAData() const >-{ >- auto surface = cairoSurfaceCoerceToImage(m_data.m_surface.get()); >- cairo_surface_flush(surface.get()); >- >- Vector<uint8_t> imageData; >- if (cairo_surface_status(surface.get())) >- return imageData; >- >- auto pixels = cairo_image_surface_get_data(surface.get()); >- imageData.append(pixels, cairo_image_surface_get_stride(surface.get()) * >- cairo_image_surface_get_height(surface.get())); >- >- return imageData; >-} >- >-NativeImagePtr ImageBuffer::nativeImage() const >-{ >- return m_data.m_surface.get(); >-} >- >-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace, RenderingMode renderingMode, const HostWindow*, bool& success) >- : m_data(IntSize(size), renderingMode) >- , m_logicalSize(size) >- , m_resolutionScale(resolutionScale) >-{ >- success = false; // Make early return mean error. >- >- float scaledWidth = ceilf(m_resolutionScale * size.width()); >- float scaledHeight = ceilf(m_resolutionScale * size.height()); >- >- // FIXME: Should we automatically use a lower resolution? >- if (!FloatSize(scaledWidth, scaledHeight).isExpressibleAsIntSize()) >- return; >- >- m_size = IntSize(scaledWidth, scaledHeight); >- m_data.m_size = m_size; >- >- if (m_size.isEmpty()) >- return; >- >-#if ENABLE(ACCELERATED_2D_CANVAS) >- if (m_data.m_renderingMode == RenderingMode::Accelerated) { >- m_data.createCairoGLSurface(); >- if (!m_data.m_surface || cairo_surface_status(m_data.m_surface.get()) != CAIRO_STATUS_SUCCESS) >- m_data.m_renderingMode = RenderingMode::Unaccelerated; // If allocation fails, fall back to non-accelerated path. >- } >- if (m_data.m_renderingMode == RenderingMode::Unaccelerated) >-#else >- ASSERT(m_data.m_renderingMode != RenderingMode::Accelerated); >-#endif >- { >- static cairo_user_data_key_t s_surfaceDataKey; >- >- int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_size.width()); >- void* surfaceData; >- if (!tryFastZeroedMalloc(m_size.height() * stride).getValue(surfaceData)) >- return; >- >- m_data.m_surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(surfaceData), CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height(), stride)); >- cairo_surface_set_user_data(m_data.m_surface.get(), &s_surfaceDataKey, surfaceData, [](void* data) { fastFree(data); }); >- } >- >- if (cairo_surface_status(m_data.m_surface.get()) != CAIRO_STATUS_SUCCESS) >- return; // create will notice we didn't set m_initialized and fail. >- >- cairoSurfaceSetDeviceScale(m_data.m_surface.get(), m_resolutionScale, m_resolutionScale); >- >- RefPtr<cairo_t> cr = adoptRef(cairo_create(m_data.m_surface.get())); >- m_data.m_platformContext.setCr(cr.get()); >- m_data.m_context = makeUnique<GraphicsContext>(GraphicsContextImplCairo::createFactory(m_data.m_platformContext)); >- success = true; >-} >- >-ImageBuffer::~ImageBuffer() = default; >- >-std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const GraphicsContext& context) >-{ >- return createCompatibleBuffer(size, ColorSpace::SRGB, context); >-} >- >-GraphicsContext& ImageBuffer::context() const >-{ >- return *m_data.m_context; >-} >- >-RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, PreserveResolution preserveResolution) >-{ >- return imageBuffer->copyImage(DontCopyBackingStore, preserveResolution); >-} >- >-RefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, PreserveResolution) const >-{ >- // copyCairoImageSurface inherits surface's device scale factor. >- if (copyBehavior == CopyBackingStore) >- return BitmapImage::create(copyCairoImageSurface(m_data.m_surface.get())); >- >- // BitmapImage will release the passed in surface on destruction >- return BitmapImage::create(RefPtr<cairo_surface_t>(m_data.m_surface)); >-} >- >-void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >-{ >- imageBuffer->draw(destContext, destRect, srcRect, options); >-} >- >-void ImageBuffer::draw(GraphicsContext& destinationContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >-{ >- if (destinationContext.paintingDisabled()) >- return; >- >- if (auto surface = nativeImage()) { >- if (&destinationContext == &context()) >- surface = cairoSurfaceCopy(surface.get()); >- >- InterpolationQualityMaintainer interpolationQualityForThisScope(destinationContext, options.interpolationQuality()); >- const auto& destinationContextState = destinationContext.state(); >- drawNativeImage(*destinationContext.platformContext(), surface.get(), destRect, srcRect, { options, destinationContextState.imageInterpolationQuality }, destinationContextState.alpha, WebCore::Cairo::ShadowState(destinationContextState)); >- } >-} >- >-void ImageBuffer::drawPattern(GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, >- const FloatPoint& phase, const FloatSize&, const ImagePaintingOptions& options) >-{ >- if (context.paintingDisabled()) >- return; >- >- if (auto surface = nativeImage()) >- Cairo::drawPattern(*context.platformContext(), surface.get(), m_size, destRect, srcRect, patternTransform, phase, options); >-} >- >-void ImageBuffer::platformTransformColorSpace(const std::array<uint8_t, 256>& lookUpTable) >-{ >- // FIXME: Enable color space conversions on accelerated canvases. >- if (cairo_surface_get_type(m_data.m_surface.get()) != CAIRO_SURFACE_TYPE_IMAGE) >- return; >- >- unsigned char* dataSrc = cairo_image_surface_get_data(m_data.m_surface.get()); >- int stride = cairo_image_surface_get_stride(m_data.m_surface.get()); >- for (int y = 0; y < m_size.height(); ++y) { >- unsigned* row = reinterpret_cast_ptr<unsigned*>(dataSrc + stride * y); >- for (int x = 0; x < m_size.width(); x++) { >- unsigned* pixel = row + x; >- Color pixelColor = colorFromPremultipliedARGB(*pixel); >- pixelColor = Color(lookUpTable[pixelColor.red()], >- lookUpTable[pixelColor.green()], >- lookUpTable[pixelColor.blue()], >- pixelColor.alpha()); >- *pixel = premultipliedARGBFromColor(pixelColor); >- } >- } >- cairo_surface_mark_dirty_rectangle(m_data.m_surface.get(), 0, 0, m_logicalSize.width(), m_logicalSize.height()); >-} >- >-RefPtr<cairo_surface_t> copySurfaceToImageAndAdjustRect(cairo_surface_t* surface, IntRect& rect) >-{ >- cairo_surface_type_t surfaceType = cairo_surface_get_type(surface); >- >- // If we already have an image, we write directly to the underlying data; >- // otherwise we create a temporary surface image >- if (surfaceType == CAIRO_SURFACE_TYPE_IMAGE) >- return surface; >- >- rect.setX(0); >- rect.setY(0); >- return adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect.width(), rect.height())); >-} >- >-template <AlphaPremultiplication premultiplied> >-RefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const IntRect& logicalRect, const ImageBufferData& data, const IntSize& size, const IntSize& logicalSize, float resolutionScale) >-{ >- // The area can overflow if the rect is too big. >- Checked<unsigned, RecordOverflow> area = 4; >- area *= rect.width(); >- area *= rect.height(); >- if (area.hasOverflowed()) >- return nullptr; >- >- auto result = Uint8ClampedArray::tryCreateUninitialized(area.unsafeGet()); >- if (!result) >- return nullptr; >- >- // Can overflow, as we are adding 2 ints. >- int endx = 0; >- if (!WTF::safeAdd(rect.x(), rect.width(), endx)) >- return nullptr; >- >- // Can overflow, as we are adding 2 ints. >- int endy = 0; >- if (!WTF::safeAdd(rect.y(), rect.height(), endy)) >- return nullptr; >- >- if (rect.x() < 0 || rect.y() < 0 || endx > size.width() || endy > size.height()) >- result->zeroFill(); >- >- int originx = rect.x(); >- int destx = 0; >- if (originx < 0) { >- destx = -originx; >- originx = 0; >- } >- >- if (endx > size.width()) >- endx = size.width(); >- int numColumns = endx - originx; >- >- int originy = rect.y(); >- int desty = 0; >- if (originy < 0) { >- desty = -originy; >- originy = 0; >- } >- >- if (endy > size.height()) >- endy = size.height(); >- int numRows = endy - originy; >- >- // Nothing will be copied, so just return the result. >- if (numColumns <= 0 || numRows <= 0) >- return result; >- >- // The size of the derived surface is in BackingStoreCoordinateSystem. >- // We need to set the device scale for the derived surface from this ImageBuffer. >- IntRect imageRect(originx, originy, numColumns, numRows); >- RefPtr<cairo_surface_t> imageSurface = copySurfaceToImageAndAdjustRect(data.m_surface.get(), imageRect); >- cairoSurfaceSetDeviceScale(imageSurface.get(), resolutionScale, resolutionScale); >- originx = imageRect.x(); >- originy = imageRect.y(); >- if (imageSurface != data.m_surface.get()) { >- // This cairo surface operation is done in LogicalCoordinateSystem. >- IntRect logicalArea = intersection(logicalRect, IntRect(0, 0, logicalSize.width(), logicalSize.height())); >- copyRectFromOneSurfaceToAnother(data.m_surface.get(), imageSurface.get(), IntSize(-logicalArea.x(), -logicalArea.y()), IntRect(IntPoint(), logicalArea.size()), IntSize()); >- } >- >- unsigned char* dataSrc = cairo_image_surface_get_data(imageSurface.get()); >- unsigned char* dataDst = result->data(); >- int stride = cairo_image_surface_get_stride(imageSurface.get()); >- unsigned destBytesPerRow = 4 * rect.width(); >- >- unsigned char* destRows = dataDst + desty * destBytesPerRow + destx * 4; >- for (int y = 0; y < numRows; ++y) { >- unsigned* row = reinterpret_cast_ptr<unsigned*>(dataSrc + stride * (y + originy)); >- for (int x = 0; x < numColumns; x++) { >- int basex = x * 4; >- unsigned* pixel = row + x + originx; >- >- // Avoid calling Color::colorFromPremultipliedARGB() because one >- // function call per pixel is too expensive. >- unsigned alpha = (*pixel & 0xFF000000) >> 24; >- unsigned red = (*pixel & 0x00FF0000) >> 16; >- unsigned green = (*pixel & 0x0000FF00) >> 8; >- unsigned blue = (*pixel & 0x000000FF); >- >- if (premultiplied == AlphaPremultiplication::Unpremultiplied) { >- if (alpha && alpha != 255) { >- red = red * 255 / alpha; >- green = green * 255 / alpha; >- blue = blue * 255 / alpha; >- } >- } >- >- destRows[basex] = red; >- destRows[basex + 1] = green; >- destRows[basex + 2] = blue; >- destRows[basex + 3] = alpha; >- } >- destRows += destBytesPerRow; >- } >- >- return result; >-} >- >-template<typename Unit> >-inline Unit logicalUnit(const Unit& value, ImageBuffer::CoordinateSystem coordinateSystemOfValue, float resolutionScale) >-{ >- if (coordinateSystemOfValue == ImageBuffer::LogicalCoordinateSystem || resolutionScale == 1.0) >- return value; >- Unit result(value); >- result.scale(1.0 / resolutionScale); >- return result; >-} >- >-template<typename Unit> >-inline Unit backingStoreUnit(const Unit& value, ImageBuffer::CoordinateSystem coordinateSystemOfValue, float resolutionScale) >-{ >- if (coordinateSystemOfValue == ImageBuffer::BackingStoreCoordinateSystem || resolutionScale == 1.0) >- return value; >- Unit result(value); >- result.scale(resolutionScale); >- return result; >-} >- >-RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const >-{ >- IntRect logicalRect = logicalUnit(rect, coordinateSystem, m_resolutionScale); >- IntRect backingStoreRect = backingStoreUnit(rect, coordinateSystem, m_resolutionScale); >- if (pixelArrayDimensions) >- *pixelArrayDimensions = backingStoreRect.size(); >- return getImageData<AlphaPremultiplication::Unpremultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale); >-} >- >-RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const >-{ >- IntRect logicalRect = logicalUnit(rect, coordinateSystem, m_resolutionScale); >- IntRect backingStoreRect = backingStoreUnit(rect, coordinateSystem, m_resolutionScale); >- if (pixelArrayDimensions) >- *pixelArrayDimensions = backingStoreRect.size(); >- return getImageData<AlphaPremultiplication::Premultiplied>(backingStoreRect, logicalRect, m_data, m_size, m_logicalSize, m_resolutionScale); >-} >- >-void ImageBuffer::putByteArray(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem) >-{ >- IntRect scaledSourceRect = backingStoreUnit(sourceRect, coordinateSystem, m_resolutionScale); >- IntSize scaledSourceSize = backingStoreUnit(sourceSize, coordinateSystem, m_resolutionScale); >- IntPoint scaledDestPoint = backingStoreUnit(destPoint, coordinateSystem, m_resolutionScale); >- IntRect logicalSourceRect = logicalUnit(sourceRect, coordinateSystem, m_resolutionScale); >- IntPoint logicalDestPoint = logicalUnit(destPoint, coordinateSystem, m_resolutionScale); >- >- ASSERT(scaledSourceRect.width() > 0); >- ASSERT(scaledSourceRect.height() > 0); >- >- int originx = scaledSourceRect.x(); >- int destx = scaledDestPoint.x() + scaledSourceRect.x(); >- int logicalDestx = logicalDestPoint.x() + logicalSourceRect.x(); >- ASSERT(destx >= 0); >- ASSERT(destx < m_size.width()); >- ASSERT(originx >= 0); >- ASSERT(originx <= scaledSourceRect.maxX()); >- >- int endx = scaledDestPoint.x() + scaledSourceRect.maxX(); >- int logicalEndx = logicalDestPoint.x() + logicalSourceRect.maxX(); >- ASSERT(endx <= m_size.width()); >- >- int numColumns = endx - destx; >- int logicalNumColumns = logicalEndx - logicalDestx; >- >- int originy = scaledSourceRect.y(); >- int desty = scaledDestPoint.y() + scaledSourceRect.y(); >- int logicalDesty = logicalDestPoint.y() + logicalSourceRect.y(); >- ASSERT(desty >= 0); >- ASSERT(desty < m_size.height()); >- ASSERT(originy >= 0); >- ASSERT(originy <= scaledSourceRect.maxY()); >- >- int endy = scaledDestPoint.y() + scaledSourceRect.maxY(); >- int logicalEndy = logicalDestPoint.y() + logicalSourceRect.maxY(); >- ASSERT(endy <= m_size.height()); >- int numRows = endy - desty; >- int logicalNumRows = logicalEndy - logicalDesty; >- >- // The size of the derived surface is in BackingStoreCoordinateSystem. >- // We need to set the device scale for the derived surface from this ImageBuffer. >- IntRect imageRect(destx, desty, numColumns, numRows); >- RefPtr<cairo_surface_t> imageSurface = copySurfaceToImageAndAdjustRect(m_data.m_surface.get(), imageRect); >- cairoSurfaceSetDeviceScale(imageSurface.get(), m_resolutionScale, m_resolutionScale); >- destx = imageRect.x(); >- desty = imageRect.y(); >- >- uint8_t* pixelData = cairo_image_surface_get_data(imageSurface.get()); >- >- unsigned srcBytesPerRow = 4 * scaledSourceSize.width(); >- int stride = cairo_image_surface_get_stride(imageSurface.get()); >- >- const uint8_t* srcRows = source.data() + originy * srcBytesPerRow + originx * 4; >- for (int y = 0; y < numRows; ++y) { >- unsigned* row = reinterpret_cast_ptr<unsigned*>(pixelData + stride * (y + desty)); >- for (int x = 0; x < numColumns; x++) { >- int basex = x * 4; >- unsigned* pixel = row + x + destx; >- >- // Avoid calling Color::premultipliedARGBFromColor() because one >- // function call per pixel is too expensive. >- unsigned red = srcRows[basex]; >- unsigned green = srcRows[basex + 1]; >- unsigned blue = srcRows[basex + 2]; >- unsigned alpha = srcRows[basex + 3]; >- >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied) { >- if (alpha != 255) { >- red = (red * alpha + 254) / 255; >- green = (green * alpha + 254) / 255; >- blue = (blue * alpha + 254) / 255; >- } >- } >- >- *pixel = (alpha << 24) | red << 16 | green << 8 | blue; >- } >- srcRows += srcBytesPerRow; >- } >- >- // This cairo surface operation is done in LogicalCoordinateSystem. >- cairo_surface_mark_dirty_rectangle(imageSurface.get(), logicalDestx, logicalDesty, logicalNumColumns, logicalNumRows); >- >- if (imageSurface != m_data.m_surface.get()) { >- // This cairo surface operation is done in LogicalCoordinateSystem. >- copyRectFromOneSurfaceToAnother(imageSurface.get(), m_data.m_surface.get(), IntSize(), IntRect(0, 0, logicalNumColumns, logicalNumRows), IntSize(logicalDestPoint.x() + logicalSourceRect.x(), logicalDestPoint.y() + logicalSourceRect.y())); >- } >-} >- >-String ImageBuffer::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const >-{ >- Vector<uint8_t> encodedImage = toData(mimeType, quality); >- if (encodedImage.isEmpty()) >- return "data:,"; >- >- Vector<char> base64Data; >- base64Encode(encodedImage.data(), encodedImage.size(), base64Data); >- >- return "data:" + mimeType + ";base64," + base64Data; >-} >- >-Vector<uint8_t> ImageBuffer::toData(const String& mimeType, Optional<double> quality) const >-{ >- ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); >- cairo_surface_t* image = cairo_get_target(context().platformContext()->cr()); >- return data(image, mimeType, quality); >-} >- >-#if ENABLE(ACCELERATED_2D_CANVAS) && !USE(COORDINATED_GRAPHICS) >-void ImageBufferData::paintToTextureMapper(TextureMapper& textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity) >-{ >- ASSERT(m_texture); >- >- // Cairo may change the active context, so we make sure to change it back after flushing. >- GLContext* previousActiveContext = GLContext::current(); >- cairo_surface_flush(m_surface.get()); >- previousActiveContext->makeContextCurrent(); >- >- static_cast<TextureMapperGL&>(textureMapper).drawTexture(m_texture, TextureMapperGL::ShouldBlend, m_size, targetRect, matrix, opacity); >-} >-#endif >- >-PlatformLayer* ImageBuffer::platformLayer() const >-{ >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#if USE(NICOSIA) >- if (m_data.m_renderingMode == RenderingMode::Accelerated) >- return m_data.m_nicosiaLayer.get(); >-#else >- if (m_data.m_texture) >- return const_cast<ImageBufferData*>(&m_data); >-#endif >-#endif >- return 0; >-} >- >-bool ImageBuffer::copyToPlatformTexture(GraphicsContextGLOpenGL&, GCGLenum target, PlatformGLObject destinationTexture, GCGLenum internalformat, bool premultiplyAlpha, bool flipY) >-{ >-#if ENABLE(ACCELERATED_2D_CANVAS) >- ASSERT_WITH_MESSAGE(m_resolutionScale == 1.0, "Since the HiDPI Canvas feature is removed, the resolution factor here is always 1."); >- if (premultiplyAlpha || flipY) >- return false; >- >- if (!m_data.m_texture) >- return false; >- >- GCGLenum bindTextureTarget; >- switch (target) { >- case GL_TEXTURE_2D: >- bindTextureTarget = GL_TEXTURE_2D; >- break; >- case GL_TEXTURE_CUBE_MAP_POSITIVE_X: >- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: >- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: >- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: >- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: >- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: >- bindTextureTarget = GL_TEXTURE_CUBE_MAP; >- break; >- default: >- return false; >- } >- >- cairo_surface_flush(m_data.m_surface.get()); >- >- std::unique_ptr<GLContext> context = GLContext::createOffscreenContext(&PlatformDisplay::sharedDisplayForCompositing()); >- context->makeContextCurrent(); >- uint32_t fbo; >- glGenFramebuffers(1, &fbo); >- glBindFramebuffer(GL_FRAMEBUFFER, fbo); >- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_data.m_texture, 0); >- glBindTexture(bindTextureTarget, destinationTexture); >- glCopyTexImage2D(target, 0, internalformat, 0, 0, m_size.width(), m_size.height(), 0); >- glBindTexture(bindTextureTarget, 0); >- glBindFramebuffer(GL_FRAMEBUFFER, 0); >- glFlush(); >- glDeleteFramebuffers(1, &fbo); >- return true; >-#else >- UNUSED_PARAM(target); >- UNUSED_PARAM(destinationTexture); >- UNUSED_PARAM(internalformat); >- UNUSED_PARAM(premultiplyAlpha); >- UNUSED_PARAM(flipY); >- return false; >-#endif >-} >- >-} // namespace WebCore >- >-#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..076af40896baacd80d9f1c5efaa790a149b8dd7f >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.cpp >@@ -0,0 +1,126 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferCairoBackend.h" >+ >+#include "BitmapImage.h" >+#include "CairoOperations.h" >+#include "Color.h" >+#include "ColorUtilities.h" >+#include "GraphicsContext.h" >+#include "GraphicsContextImplCairo.h" >+#include "ImageBufferUtilitiesCairo.h" >+#include "MIMETypeRegistry.h" >+#include "PlatformContextCairo.h" >+#include <cairo.h> >+#include <wtf/text/Base64.h> >+ >+#if USE(CAIRO) >+ >+namespace WebCore { >+ >+RefPtr<Image> ImageBufferCairoBackend::copyImage(BackingStoreCopy copyBehavior, PreserveResolution) const >+{ >+ // BitmapImage will release the passed in surface on destruction >+ return BitmapImage::create(copyNativeImage(copyBehavior)); >+} >+ >+void ImageBufferCairoBackend::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >+{ >+ InterpolationQualityMaintainer interpolationQualityForThisScope(destContext, options.interpolationQuality()); >+ const auto& destinationContextState = destContext.state(); >+ >+ if (auto image = copyNativeImage(&destContext == &context() ? CopyBackingStore : DontCopyBackingStore)) >+ drawNativeImage(*destContext.platformContext(), image.get(), destRect, srcRect, { options, destinationContextState.imageInterpolationQuality }, destinationContextState.alpha, WebCore::Cairo::ShadowState(destinationContextState)); >+} >+ >+void ImageBufferCairoBackend::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize&, const ImagePaintingOptions& options) >+{ >+ if (auto image = copyNativeImage(&destContext == &context() ? CopyBackingStore : DontCopyBackingStore)) >+ Cairo::drawPattern(*destContext.platformContext(), image.get(), m_logicalSize, destRect, srcRect, patternTransform, phase, options); >+} >+ >+void ImageBufferCairoBackend::transformColorSpace(ColorSpace srcColorSpace, ColorSpace destColorSpace) >+{ >+ if (srcColorSpace == destColorSpace) >+ return; >+ >+ // only sRGB <-> linearRGB are supported at the moment >+ if ((srcColorSpace != ColorSpace::LinearRGB && srcColorSpace != ColorSpace::SRGB) >+ || (destColorSpace != ColorSpace::LinearRGB && destColorSpace != ColorSpace::SRGB)) >+ return; >+ >+ if (destColorSpace == ColorSpace::LinearRGB) { >+ static const std::array<uint8_t, 256> linearRgbLUT = [] { >+ std::array<uint8_t, 256> array; >+ for (unsigned i = 0; i < 256; i++) { >+ float color = i / 255.0f; >+ color = sRGBToLinearColorComponent(color); >+ array[i] = static_cast<uint8_t>(round(color * 255)); >+ } >+ return array; >+ }(); >+ platformTransformColorSpace(linearRgbLUT); >+ } else if (destColorSpace == ColorSpace::SRGB) { >+ static const std::array<uint8_t, 256> deviceRgbLUT= [] { >+ std::array<uint8_t, 256> array; >+ for (unsigned i = 0; i < 256; i++) { >+ float color = i / 255.0f; >+ color = linearToSRGBColorComponent(color); >+ array[i] = static_cast<uint8_t>(round(color * 255)); >+ } >+ return array; >+ }(); >+ platformTransformColorSpace(deviceRgbLUT); >+ } >+} >+ >+String ImageBufferCairoBackend::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const >+{ >+ Vector<uint8_t> encodedImage = toData(mimeType, quality); >+ if (encodedImage.isEmpty()) >+ return "data:,"; >+ >+ Vector<char> base64Data; >+ base64Encode(encodedImage.data(), encodedImage.size(), base64Data); >+ >+ return "data:" + mimeType + ";base64," + base64Data; >+} >+ >+Vector<uint8_t> ImageBufferCairoBackend::toData(const String& mimeType, Optional<double> quality) const >+{ >+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); >+ cairo_surface_t* image = cairo_get_target(context().platformContext()->cr()); >+ return data(image, mimeType, quality); >+} >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.h b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..23b919ad522ea178b32c009f5d88d5d716def3a1 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoBackend.h >@@ -0,0 +1,59 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(CAIRO) >+ >+#include "ImageBufferBackend.h" >+ >+namespace WebCore { >+ >+class ImageBufferCairoBackend : public ImageBufferBackend { >+public: >+ RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const override; >+ >+ void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) override; >+ void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions&) override; >+ >+ void transformColorSpace(ColorSpace srcColorSpace, ColorSpace destColorSpace) override; >+ >+ String toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const override; >+ Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override; >+ >+protected: >+ using ImageBufferBackend::ImageBufferBackend; >+ >+ ColorFormat backendColorFormat() const override { return ColorFormat::BGRA; } >+ virtual void platformTransformColorSpace(const std::array<uint8_t, 256>&) { } >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..d36372f919e7ece8cbc6a263c489c99e0e876243 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.cpp >@@ -0,0 +1,268 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferCairoGLSurfaceBackend.h" >+ >+#if USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS) >+ >+namespace WebCore { >+ >+#include "GLContext.h" >+#include "TextureMapperGL.h" >+#include <wtf/IsoMallocInlines.h> >+ >+#if USE(EGL) >+#if USE(LIBEPOXY) >+#include "EpoxyEGL.h" >+#else >+#include <EGL/egl.h> >+#endif >+#endif >+#include <cairo-gl.h> >+ >+#if USE(LIBEPOXY) >+#include <epoxy/gl.h> >+#elif USE(OPENGL_ES) >+#include <GLES2/gl2.h> >+#else >+#include "OpenGLShims.h" >+#endif >+ >+#if USE(COORDINATED_GRAPHICS) >+#include "TextureMapperPlatformLayerBuffer.h" >+#include "TextureMapperPlatformLayerProxy.h" >+#endif >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBufferCairoGLSurfaceBackend); >+ >+static inline void clearSurface(cairo_surface_t* surface) >+{ >+ RefPtr<cairo_t> cr = adoptRef(cairo_create(surface)); >+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR); >+ cairo_paint(cr.get()); >+} >+ >+std::unique_ptr<ImageBufferCairoGLSurfaceBackend> ImageBufferCairoGLSurfaceBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow*) >+{ >+ IntSize backendSize = calculateBackendSize(size, resolutionScale); >+ if (backendSize.isEmpty()) >+ return nullptr; >+ >+ auto* context = PlatformDisplay::sharedDisplayForCompositing().sharingGLContext(); >+ context->makeContextCurrent(); >+ >+ // We must generate the texture ourselves, because there is no Cairo API for extracting it >+ // from a pre-existing surface. >+ uint32_t texture >+ glGenTextures(1, &texture); >+ glBindTexture(GL_TEXTURE_2D, texture); >+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); >+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); >+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); >+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); >+ >+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); >+ >+ glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, backendSize.width(), backendSize.height(), 0 /* border */, GL_RGBA, GL_UNSIGNED_BYTE, 0); >+ >+ cairo_device_t* device = context->cairoDevice(); >+ >+ // Thread-awareness is a huge performance hit on non-Intel drivers. >+ cairo_gl_device_set_thread_aware(device, FALSE); >+ >+ auto surface = adoptRef(cairo_gl_surface_create_for_texture(device, CAIRO_CONTENT_COLOR_ALPHA, texture, backendSize.width(), backendSize.height())); >+ if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) >+ return nullptr; >+ >+ clearSurface(surface.get()); >+ >+ return std::unique_ptr<ImageBufferCairoGLSurfaceBackend>(new ImageBufferCairoGLSurfaceBackend(size, backendSize, resolutionScale, colorSpace, WTFMove(surface), texture)); >+} >+ >+std::unique_ptr<ImageBufferCairoGLSurfaceBackend> ImageBufferCairoGLSurfaceBackend::create(const FloatSize& size, const GraphicsContext&) >+{ >+ return ImageBufferCairoGLSurfaceBackend::create(size, 1, ColorSpace::SRGB, nullptr); >+} >+ >+ImageBufferCairoGLSurfaceBackend::ImageBufferCairoGLSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, RefPtr<cairo_surface_t>&& surface, uint32_t texture) >+ : ImageBufferCairoSurfaceBackend(logicalSize, backendSize, resolutionScale, colorSpace, WTFMove(surface)) >+ , m_texture(texture) >+{ >+#if USE(COORDINATED_GRAPHICS) >+#if USE(NICOSIA) >+ m_nicosiaLayer = Nicosia::ContentLayer::create(Nicosia::ContentLayerTextureMapperImpl::createFactory(*this)); >+#else >+ m_platformLayerProxy = adoptRef(new TextureMapperPlatformLayerProxy); >+#endif >+#endif >+} >+ >+ImageBufferCairoGLSurfaceBackend::~ImageBufferCairoGLSurfaceBackend() >+{ >+#if USE(COORDINATED_GRAPHICS) && USE(NICOSIA) >+ downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).invalidateClient(); >+#endif >+ >+ GLContext* previousActiveContext = GLContext::current(); >+ PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent(); >+ >+ if (m_texture) >+ glDeleteTextures(1, &m_texture); >+ >+#if USE(COORDINATED_GRAPHICS) >+ if (m_compositorTexture) >+ glDeleteTextures(1, &m_compositorTexture); >+#endif >+ >+ if (previousActiveContext) >+ previousActiveContext->makeContextCurrent(); >+} >+ >+PlatformLayer* ImageBuffer::platformLayer() const >+{ >+#if USE(NICOSIA) >+ return m_nicosiaLayer.get(); >+#else >+ if (m_texture) >+ return this; >+#endif >+ return nullptr; >+} >+ >+bool ImageBufferCairoGLSurfaceBackend::copyToPlatformTexture(GCGLenum target, PlatformGLObject destinationTexture, GCGLenum internalformat, bool premultiplyAlpha, bool flipY) >+{ >+ ASSERT_WITH_MESSAGE(m_resolutionScale == 1.0, "Since the HiDPI Canvas feature is removed, the resolution factor here is always 1."); >+ if (premultiplyAlpha || flipY) >+ return false; >+ >+ if (!m_texture) >+ return false; >+ >+ GC3Denum bindTextureTarget; >+ switch (target) { >+ case GL_TEXTURE_2D: >+ bindTextureTarget = GL_TEXTURE_2D; >+ break; >+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X: >+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: >+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: >+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: >+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: >+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: >+ bindTextureTarget = GL_TEXTURE_CUBE_MAP; >+ break; >+ default: >+ return false; >+ } >+ >+ cairo_surface_flush(m_surface.get()); >+ >+ std::unique_ptr<GLContext> context = GLContext::createOffscreenContext(&PlatformDisplay::sharedDisplayForCompositing()); >+ context->makeContextCurrent(); >+ uint32_t fbo; >+ glGenFramebuffers(1, &fbo); >+ glBindFramebuffer(GL_FRAMEBUFFER, fbo); >+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0); >+ glBindTexture(bindTextureTarget, destinationTexture); >+ glCopyTexImage2D(target, 0, internalformat, 0, 0, m_backendSize.width(), m_backendSize.height(), 0); >+ glBindTexture(bindTextureTarget, 0); >+ glBindFramebuffer(GL_FRAMEBUFFER, 0); >+ glFlush(); >+ glDeleteFramebuffers(1, &fbo); >+ return true; >+} >+ >+#if USE(COORDINATED_GRAPHICS) >+void ImageBufferCairoGLSurfaceBackend::createCompositorBuffer() >+{ >+ auto* context = PlatformDisplay::sharedDisplayForCompositing().sharingGLContext(); >+ context->makeContextCurrent(); >+ >+ glGenTextures(1, &m_compositorTexture); >+ glBindTexture(GL_TEXTURE_2D, m_compositorTexture); >+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); >+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); >+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); >+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); >+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); >+ glTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, m_backendSize.width(), m_backendSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); >+ >+ m_compositorSurface = adoptRef(cairo_gl_surface_create_for_texture(context->cairoDevice(), CAIRO_CONTENT_COLOR_ALPHA, m_compositorTexture, m_backendSize.width(), m_backendSize.height())); >+ m_compositorCr = adoptRef(cairo_create(m_compositorSurface.get())); >+ cairo_set_antialias(m_compositorCr.get(), CAIRO_ANTIALIAS_NONE); >+} >+ >+void ImageBufferCairoGLSurfaceBackend::swapBuffersIfNeeded() >+{ >+ GLContext* previousActiveContext = GLContext::current(); >+ >+ if (!m_compositorTexture) { >+ createCompositorBuffer(); >+ >+ auto proxyOperation = >+ [this](TextureMapperPlatformLayerProxy& proxy) >+ { >+ LockHolder holder(proxy.lock()); >+ proxy.pushNextBuffer(makeUnique<TextureMapperPlatformLayerBuffer>(m_compositorTexture, m_backendSize, TextureMapperGL::ShouldBlend, GL_RGBA)); >+ }; >+#if USE(NICOSIA) >+ proxyOperation(downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).proxy()); >+#else >+ proxyOperation(*m_platformLayerProxy); >+#endif >+ } >+ >+ // It would be great if we could just swap the buffers here as we do with webgl, but that breaks the cases >+ // where one frame uses the content already rendered in the previous frame. So we just copy the content >+ // into the compositor buffer. >+ cairo_set_source_surface(m_compositorCr.get(), m_surface.get(), 0, 0); >+ cairo_set_operator(m_compositorCr.get(), CAIRO_OPERATOR_SOURCE); >+ cairo_paint(m_compositorCr.get()); >+ >+ if (previousActiveContext) >+ previousActiveContext->makeContextCurrent(); >+} >+#else >+void ImageBufferCairoGLSurfaceBackend::paintToTextureMapper(TextureMapper& textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity) >+{ >+ ASSERT(m_texture); >+ >+ // Cairo may change the active context, so we make sure to change it back after flushing. >+ GLContext* previousActiveContext = GLContext::current(); >+ cairo_surface_flush(m_surface.get()); >+ previousActiveContext->makeContextCurrent(); >+ >+ static_cast<TextureMapperGL&>(textureMapper).drawTexture(m_texture, TextureMapperGL::ShouldBlend, m_backendSize, targetRect, matrix, opacity); >+} >+#endif >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.h b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..cdf0fae7e2c349e2164198455d418c3cab6747b4 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoGLSurfaceBackend.h >@@ -0,0 +1,92 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS) >+ >+#include "ImageBufferCairoSurfaceBackend.h" >+#include <wtf/IsoMalloc.h> >+ >+#if USE(NICOSIA) >+#include "NicosiaContentLayerTextureMapperImpl.h" >+#else >+#include "PlatformLayer.h" >+#endif >+ >+namespace WebCore { >+ >+class ImageBufferCairoGLSurfaceBackend >+#if USE(NICOSIA) >+ : public Nicosia::ContentLayerTextureMapperImpl::Client >+#else >+ : public PlatformLayer >+#endif >+ , public ImageBufferCairoSurfaceBackend { >+ WTF_MAKE_ISO_ALLOCATED(ImageBufferCairoGLSurfaceBackend); >+ WTF_MAKE_NONCOPYABLE(ImageBufferCairoGLSurfaceBackend); >+public: >+ static std::unique_ptr<ImageBufferCairoGLSurfaceBackend> create(const FloatSize&, float resolutionScale, ColorSpace, const HostWindow*); >+ static std::unique_ptr<ImageBufferCairoGLSurfaceBackend> create(const FloatSize&, const GraphicsContext&); >+ >+ ~ImageBufferCairoGLSurfaceBackend(); >+ >+ PlatformLayer* platformLayer() const override; >+ bool copyToPlatformTexture(GCGLenum target, PlatformGLObject destinationTexture, GCGLenum internalformat, bool premultiplyAlpha, bool flipY) override; >+ >+private: >+ ImageBufferCairoGLSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace, RefPtr<cairo_surface_t>&&); >+ >+#if USE(COORDINATED_GRAPHICS) >+ void createCompositorBuffer(); >+ void swapBuffersIfNeeded() override; >+#if !USE(NICOSIA) >+ RefPtr<TextureMapperPlatformLayerProxy> proxy() const override { return m_platformLayerProxy.copyRef(); } >+#endif >+#else >+ void paintToTextureMapper(TextureMapper&, const FloatRect& target, const TransformationMatrix&, float opacity); >+#endif >+ >+#if USE(COORDINATED_GRAPHICS) >+#if USE(NICOSIA) >+ RefPtr<Nicosia::ContentLayer> m_nicosiaLayer; >+#else >+ RefPtr<TextureMapperPlatformLayerProxy> m_platformLayerProxy; >+#endif >+ uint32_t m_texture; >+ RefPtr<cairo_surface_t> m_compositorSurface; >+ RefPtr<cairo_t> m_compositorCr; >+ uint32_t m_compositorTexture { 0 }; >+#endif >+ uint32_t m_texture { 0 }; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..55f2dde98eb74e4e2103cac4418f7b58ea9e1cfc >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp >@@ -0,0 +1,93 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferCairoImageSurfaceBackend.h" >+ >+#if USE(CAIRO) >+ >+#include "Color.h" >+#include <cairo.h> >+#include <wtf/IsoMallocInlines.h> >+ >+namespace WebCore { >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBufferCairoImageSurfaceBackend); >+ >+std::unique_ptr<ImageBufferCairoImageSurfaceBackend> ImageBufferCairoImageSurfaceBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow*) >+{ >+ static cairo_user_data_key_t s_surfaceDataKey; >+ >+ IntSize backendSize = calculateBackendSize(size, resolutionScale); >+ if (backendSize.isEmpty()) >+ return nullptr; >+ >+ int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, backendSize.width()); >+ void* surfaceData; >+ if (!tryFastZeroedMalloc(backendSize.height() * stride).getValue(surfaceData)) >+ return nullptr; >+ >+ auto surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(surfaceData), CAIRO_FORMAT_ARGB32, backendSize.width(), backendSize.height(), stride)); >+ cairo_surface_set_user_data(surface.get(), &s_surfaceDataKey, surfaceData, [](void* data) { >+ fastFree(data); >+ }); >+ >+ return std::unique_ptr<ImageBufferCairoImageSurfaceBackend>(new ImageBufferCairoImageSurfaceBackend(size, backendSize, resolutionScale, colorSpace, WTFMove(surface))); >+} >+ >+std::unique_ptr<ImageBufferCairoImageSurfaceBackend> ImageBufferCairoImageSurfaceBackend::create(const FloatSize& size, const GraphicsContext&) >+{ >+ return ImageBufferCairoImageSurfaceBackend::create(size, 1, ColorSpace::SRGB, nullptr); >+} >+ >+ImageBufferCairoImageSurfaceBackend::ImageBufferCairoImageSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, RefPtr<cairo_surface_t>&& surface) >+ : ImageBufferCairoSurfaceBackend(logicalSize, backendSize, resolutionScale, colorSpace, WTFMove(surface)) >+{ >+ ASSERT(cairo_surface_get_type(m_surface.get()) == CAIRO_SURFACE_TYPE_IMAGE); >+} >+ >+void ImageBufferCairoImageSurfaceBackend::platformTransformColorSpace(const std::array<uint8_t, 256>& lookUpTable) >+{ >+ unsigned char* dataSrc = cairo_image_surface_get_data(m_surface.get()); >+ int stride = cairo_image_surface_get_stride(m_surface.get()); >+ for (int y = 0; y < m_logicalSize.height(); ++y) { >+ unsigned* row = reinterpret_cast_ptr<unsigned*>(dataSrc + stride * y); >+ for (int x = 0; x < m_logicalSize.width(); x++) { >+ unsigned* pixel = row + x; >+ Color pixelColor = colorFromPremultipliedARGB(*pixel); >+ pixelColor = Color(lookUpTable[pixelColor.red()], lookUpTable[pixelColor.green()], lookUpTable[pixelColor.blue()], pixelColor.alpha()); >+ *pixel = premultipliedARGBFromColor(pixelColor); >+ } >+ } >+ cairo_surface_mark_dirty_rectangle(m_surface.get(), 0, 0, m_logicalSize.width(), m_logicalSize.height()); >+} >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..16003794fdaa94732b61557c41e844231a98a701 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.h >@@ -0,0 +1,54 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(CAIRO) >+ >+#include "ImageBufferCairoSurfaceBackend.h" >+#include <wtf/IsoMalloc.h> >+ >+namespace WebCore { >+ >+class ImageBufferCairoImageSurfaceBackend : public ImageBufferCairoSurfaceBackend { >+ WTF_MAKE_ISO_ALLOCATED(ImageBufferCairoImageSurfaceBackend); >+ WTF_MAKE_NONCOPYABLE(ImageBufferCairoImageSurfaceBackend); >+public: >+ static std::unique_ptr<ImageBufferCairoImageSurfaceBackend> create(const FloatSize&, float resolutionScale, ColorSpace, const HostWindow*); >+ static std::unique_ptr<ImageBufferCairoImageSurfaceBackend> create(const FloatSize&, const GraphicsContext&); >+ >+private: >+ ImageBufferCairoImageSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace, RefPtr<cairo_surface_t>&&); >+ >+ void platformTransformColorSpace(const std::array<uint8_t, 256>& lookUpTable) override; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..e2d15f0ba22210f7a174ba707ed26180c18fea4c >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.cpp >@@ -0,0 +1,134 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferCairoSurfaceBackend.h" >+ >+#include "BitmapImage.h" >+#include "CairoOperations.h" >+#include "Color.h" >+#include "ColorUtilities.h" >+#include "GraphicsContext.h" >+#include "GraphicsContextImplCairo.h" >+#include "ImageBufferUtilitiesCairo.h" >+#include "ImageData.h" >+#include <cairo.h> >+ >+#if USE(CAIRO) >+ >+namespace WebCore { >+ >+ImageBufferCairoSurfaceBackend::ImageBufferCairoSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, RefPtr<cairo_surface_t>&& surface) >+ : ImageBufferCairoBackend(logicalSize, backendSize, resolutionScale, colorSpace) >+ , m_surface(WTFMove(surface)) >+{ >+ ASSERT(cairo_surface_status(m_surface.get()) == CAIRO_STATUS_SUCCESS); >+ >+ RefPtr<cairo_t> cr = adoptRef(cairo_create(m_surface.get())); >+ m_platformContext.setCr(cr.get()); >+ m_context = makeUnique<GraphicsContext>(GraphicsContextImplCairo::createFactory(m_platformContext)); >+} >+ >+GraphicsContext& ImageBufferCairoSurfaceBackend::context() const >+{ >+ return *m_context; >+} >+ >+unsigned ImageBufferCairoSurfaceBackend::bytesPerRow() const >+{ >+ return cairo_image_surface_get_stride(m_surface.get()); >+} >+ >+NativeImagePtr ImageBufferCairoSurfaceBackend::copyNativeImage(BackingStoreCopy copyBehavior) const >+{ >+ switch (copyBehavior) { >+ case CopyBackingStore: { >+ auto copy = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, >+ cairo_image_surface_get_width(m_surface.get()), >+ cairo_image_surface_get_height(m_surface.get()))); >+ >+ auto cr = adoptRef(cairo_create(copy.get())); >+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE); >+ cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0); >+ cairo_paint(cr.get()); >+ >+ return copy; >+ } >+ >+ case DontCopyBackingStore: >+ return m_surface; >+ } >+ >+ ASSERT_NOT_REACHED(); >+ return nullptr; >+} >+ >+NativeImagePtr ImageBufferCairoSurfaceBackend::cairoSurfaceCoerceToImage() const >+{ >+ BackingStoreCopy copyBehavior; >+ if (cairo_surface_get_type(m_surface.get()) == CAIRO_SURFACE_TYPE_IMAGE && cairo_surface_get_content(m_surface.get()) == CAIRO_CONTENT_COLOR_ALPHA) >+ copyBehavior = DontCopyBackingStore; >+ else >+ copyBehavior = CopyBackingStore; >+ return copyNativeImage(copyBehavior); >+} >+ >+Vector<uint8_t> ImageBufferCairoSurfaceBackend::toBGRAData() const >+{ >+ auto surface = cairoSurfaceCoerceToImage(); >+ cairo_surface_flush(surface.get()); >+ >+ Vector<uint8_t> imageData; >+ if (cairo_surface_status(surface.get())) >+ return imageData; >+ >+ auto pixels = cairo_image_surface_get_data(surface.get()); >+ imageData.append(pixels, cairo_image_surface_get_stride(surface.get()) * >+ cairo_image_surface_get_height(surface.get())); >+ >+ return imageData; >+} >+ >+RefPtr<ImageData> ImageBufferCairoSurfaceBackend::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const >+{ >+ return ImageBufferBackend::getImageData(outputFormat, srcRect, cairo_image_surface_get_data(m_surface.get())); >+} >+ >+void ImageBufferCairoSurfaceBackend::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint) >+{ >+ ImageBufferBackend::putImageData(inputFormat, imageData, srcRect, destPoint, cairo_image_surface_get_data(m_surface.get())); >+ >+ IntRect srcRectScaled = toBackendCoordinates(srcRect); >+ IntPoint destPointScaled = toBackendCoordinates(destPoint); >+ cairo_surface_mark_dirty_rectangle(m_surface.get(), destPointScaled.x(), destPointScaled.y(), srcRectScaled.width(), srcRectScaled.height()); >+} >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c949ff373748824551e3e4efe5a2b4d6693f0553 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairoSurfaceBackend.h >@@ -0,0 +1,62 @@ >+/* >+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org> >+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(CAIRO) >+ >+#include "ImageBufferCairoBackend.h" >+#include "PlatformContextCairo.h" >+ >+namespace WebCore { >+ >+class ImageBufferCairoSurfaceBackend : public ImageBufferCairoBackend { >+public: >+ GraphicsContext& context() const override; >+ >+ NativeImagePtr copyNativeImage(BackingStoreCopy) const override; >+ >+ Vector<uint8_t> toBGRAData() const override; >+ RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect&) const override; >+ void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint) override; >+ >+protected: >+ ImageBufferCairoSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace, RefPtr<cairo_surface_t>&&); >+ >+ NativeImagePtr cairoSurfaceCoerceToImage() const; >+ unsigned bytesPerRow() const override; >+ >+ mutable RefPtr<cairo_surface_t> m_surface; >+ PlatformContextCairo m_platformContext { nullptr }; >+ std::unique_ptr<GraphicsContext> m_context; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(CAIRO) >diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferDataCairo.h b/Source/WebCore/platform/graphics/cairo/ImageBufferDataCairo.h >deleted file mode 100644 >index 2a61e359946ef4bad6923fdbf7564a2e39f769c4..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/cairo/ImageBufferDataCairo.h >+++ /dev/null >@@ -1,101 +0,0 @@ >-/* >- * Copyright (C) 2008 Google Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#ifndef ImageBufferDataCairo_h >-#define ImageBufferDataCairo_h >- >-#if USE(CAIRO) >- >-#include "PlatformContextCairo.h" >-#include "RefPtrCairo.h" >- >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#include "PlatformLayer.h" >-#include "TextureMapper.h" >-#include "TextureMapperPlatformLayer.h" >-#include "TextureMapperPlatformLayerProxyProvider.h" >-#endif >- >-#if ENABLE(ACCELERATED_2D_CANVAS) && USE(NICOSIA) >-#include "NicosiaContentLayerTextureMapperImpl.h" >-#endif >- >-namespace WebCore { >- >-class IntSize; >-class TextureMapperPlatformLayerProxy; >- >-class ImageBufferData >-#if ENABLE(ACCELERATED_2D_CANVAS) >-#if USE(NICOSIA) >- : public Nicosia::ContentLayerTextureMapperImpl::Client >-#else >- : public PlatformLayer >-#endif >-#endif >-{ >-public: >- ImageBufferData(const IntSize&, RenderingMode); >- virtual ~ImageBufferData(); >- >- RefPtr<cairo_surface_t> m_surface; >- PlatformContextCairo m_platformContext; >- std::unique_ptr<GraphicsContext> m_context; >- IntSize m_size; >- RenderingMode m_renderingMode; >- >-#if ENABLE(ACCELERATED_2D_CANVAS) >- void createCairoGLSurface(); >- >-#if USE(COORDINATED_GRAPHICS) >-#if USE(NICOSIA) >- void swapBuffersIfNeeded() override; >-#else >- RefPtr<TextureMapperPlatformLayerProxy> proxy() const override; >- void swapBuffersIfNeeded() override; >-#endif >- void createCompositorBuffer(); >- >- RefPtr<cairo_surface_t> m_compositorSurface; >- uint32_t m_compositorTexture; >- RefPtr<cairo_t> m_compositorCr; >- >-#if USE(NICOSIA) >- RefPtr<Nicosia::ContentLayer> m_nicosiaLayer; >-#else >- RefPtr<TextureMapperPlatformLayerProxy> m_platformLayerProxy; >-#endif >-#else >- virtual void paintToTextureMapper(TextureMapper&, const FloatRect& target, const TransformationMatrix&, float opacity); >-#endif >- uint32_t m_texture; >-#endif >-}; >- >-} // namespace WebCore >- >-#endif // USE(CAIRO) >- >-#endif // ImageBufferDataCairo_h >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp >deleted file mode 100644 >index afd5e4ec719edb493f79dbbfabe5af93ca06709b..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp >+++ /dev/null >@@ -1,499 +0,0 @@ >-/* >- * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> >- * Copyright (C) 2008-2017 Apple Inc. All rights reserved. >- * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ImageBuffer.h" >- >-#if USE(CG) >- >-#include "BitmapImage.h" >-#include "GraphicsContext.h" >-#include "GraphicsContextCG.h" >-#include "ImageBufferUtilitiesCG.h" >-#include "ImageData.h" >-#include "IntRect.h" >-#include "MIMETypeRegistry.h" >-#include <math.h> >-#include <CoreGraphics/CoreGraphics.h> >-#include <ImageIO/ImageIO.h> >-#include <pal/spi/cg/CoreGraphicsSPI.h> >-#include <wtf/Assertions.h> >-#include <wtf/CheckedArithmetic.h> >-#include <wtf/DebugHeap.h> >-#include <wtf/MainThread.h> >-#include <wtf/RetainPtr.h> >-#include <wtf/text/Base64.h> >-#include <wtf/text/WTFString.h> >- >-#if PLATFORM(COCOA) >-#include "UTIUtilities.h" >-#endif >- >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >-#include "IOSurface.h" >-#include <pal/spi/cocoa/IOSurfaceSPI.h> >-#endif >- >-// CA uses ARGB32 for textures and ARGB32 -> ARGB32 resampling is optimized. >-#define USE_ARGB32 PLATFORM(IOS_FAMILY) >- >-namespace WebCore { >- >-DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ImageBuffer); >-DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ImageBuffer); >- >-std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const GraphicsContext& context) >-{ >- if (size.isEmpty()) >- return nullptr; >- >- RetainPtr<CGColorSpaceRef> colorSpace; >-#if PLATFORM(COCOA) >- CGContextRef cgContext = context.platformContext(); >- switch (CGContextGetType(cgContext)) { >- case kCGContextTypeBitmap: >- colorSpace = CGBitmapContextGetColorSpace(cgContext); >- break; >-#if HAVE(IOSURFACE) >- case kCGContextTypeIOSurface: >- colorSpace = CGIOSurfaceContextGetColorSpace(cgContext); >- break; >-#endif >- default: >- colorSpace = adoptCF(CGContextCopyDeviceColorSpace(cgContext)); >- } >- >- if (!colorSpace) >- colorSpace = sRGBColorSpaceRef(); >-#else >- colorSpace = sRGBColorSpaceRef(); >-#endif >- RenderingMode renderingMode = context.renderingMode(); >- IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context); >- bool success = false; >- std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(scaledSize, 1, colorSpace.get(), renderingMode, nullptr, success)); >- >- if (!success) >- return nullptr; >- >- // Set up a corresponding scale factor on the graphics context. >- buffer->context().scale(scaledSize / size); >- return buffer; >-} >- >-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, CGColorSpaceRef colorSpace, RenderingMode renderingMode, const HostWindow* hostWindow, bool& success) >- : m_logicalSize(size) >- , m_resolutionScale(resolutionScale) >-{ >- success = false; // Make early return mean failure. >- float scaledWidth = ceilf(resolutionScale * size.width()); >- float scaledHeight = ceilf(resolutionScale * size.height()); >- >- // FIXME: Should we automatically use a lower resolution? >- if (!FloatSize(scaledWidth, scaledHeight).isExpressibleAsIntSize()) >- return; >- >- m_size = IntSize(scaledWidth, scaledHeight); >- m_data.backingStoreSize = m_size; >- >- bool accelerateRendering = renderingMode == RenderingMode::Accelerated; >- if (m_size.width() <= 0 || m_size.height() <= 0) >- return; >- >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- Checked<int, RecordOverflow> width = m_size.width(); >- Checked<int, RecordOverflow> height = m_size.height(); >-#endif >- >- // Prevent integer overflows >- m_data.bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.width()); >- Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.height()) * m_data.bytesPerRow; >- if (numBytes.hasOverflowed()) >- return; >- >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- IntSize maxSize = IOSurface::maximumSize(); >- if (width.unsafeGet() > maxSize.width() || height.unsafeGet() > maxSize.height()) >- accelerateRendering = false; >-#else >- ASSERT(renderingMode == RenderingMode::Unaccelerated); >-#endif >- >- m_data.colorSpace = colorSpace; >- >- RetainPtr<CGContextRef> cgContext; >- if (accelerateRendering) { >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- FloatSize userBounds = FloatSize(width.unsafeGet(), height.unsafeGet()); >- m_data.surface = IOSurface::create(m_data.backingStoreSize, IntSize(userBounds), colorSpace); >- if (m_data.surface) { >- cgContext = m_data.surface->ensurePlatformContext(hostWindow); >- if (cgContext) >- CGContextClearRect(cgContext.get(), FloatRect(FloatPoint(), userBounds)); >- else >- m_data.surface = nullptr; >- } >-#else >- UNUSED_PARAM(hostWindow); >-#endif >- if (!cgContext) >- accelerateRendering = false; // If allocation fails, fall back to non-accelerated path. >- } >- >- if (!accelerateRendering) { >- m_data.data = ImageBufferMalloc::tryZeroedMalloc(m_data.backingStoreSize.height() * m_data.bytesPerRow.unsafeGet()); >- if (!m_data.data) >- return; >- ASSERT(!(reinterpret_cast<intptr_t>(m_data.data) & 3)); >- >-#if USE_ARGB32 >- m_data.bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; >-#else >- m_data.bitmapInfo = kCGImageAlphaPremultipliedLast; >-#endif >- cgContext = adoptCF(CGBitmapContextCreate(m_data.data, m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo)); >- const auto releaseImageData = [] (void*, const void* data, size_t) { >- ImageBufferMalloc::free(const_cast<void*>(data)); >- }; >- // Create a live image that wraps the data. >- verifyImageBufferIsBigEnough(m_data.data, numBytes.unsafeGet()); >- m_data.dataProvider = adoptCF(CGDataProviderCreateWithData(0, m_data.data, numBytes.unsafeGet(), releaseImageData)); >- >- if (!cgContext) >- return; >- >- m_data.context = makeUnique<GraphicsContext>(cgContext.get()); >- } >- >- context().scale(FloatSize(1, -1)); >- context().translate(0, -m_data.backingStoreSize.height()); >- context().applyDeviceScaleFactor(m_resolutionScale); >- >- success = true; >-} >- >-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace imageColorSpace, RenderingMode renderingMode, const HostWindow* hostWindow, bool& success) >- : ImageBuffer(size, resolutionScale, cachedCGColorSpace(imageColorSpace), renderingMode, hostWindow, success) >-{ >-} >- >-ImageBuffer::~ImageBuffer() = default; >- >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >-size_t ImageBuffer::memoryCost() const >-{ >- // memoryCost() may be invoked concurrently from a GC thread, and we need to be careful about what data we access here and how. >- // It's safe to access internalSize() because it doesn't do any pointer chasing. >- // It's safe to access m_data.surface because the surface can only be assigned during construction of this ImageBuffer. >- // It's safe to access m_data.surface->totalBytes() because totalBytes() doesn't chase pointers. >- if (m_data.surface) >- return m_data.surface->totalBytes(); >- return 4 * internalSize().width() * internalSize().height(); >-} >- >-size_t ImageBuffer::externalMemoryCost() const >-{ >- // externalMemoryCost() may be invoked concurrently from a GC thread, and we need to be careful about what data we access here and how. >- // It's safe to access m_data.surface because the surface can only be assigned during construction of this ImageBuffer. >- // It's safe to access m_data.surface->totalBytes() because totalBytes() doesn't chase pointers. >- if (m_data.surface) >- return m_data.surface->totalBytes(); >- return 0; >-} >-#endif >- >-GraphicsContext& ImageBuffer::context() const >-{ >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- if (m_data.surface) >- return m_data.surface->ensureGraphicsContext(); >-#endif >- return *m_data.context; >-} >- >-void ImageBuffer::flushContext() const >-{ >- CGContextFlush(context().platformContext()); >-} >- >-static RetainPtr<CGImageRef> createCroppedImageIfNecessary(CGImageRef image, const IntSize& bounds) >-{ >- if (image && (CGImageGetWidth(image) != static_cast<size_t>(bounds.width()) || CGImageGetHeight(image) != static_cast<size_t>(bounds.height()))) >- return adoptCF(CGImageCreateWithImageInRect(image, CGRectMake(0, 0, bounds.width(), bounds.height()))); >- return image; >-} >- >-static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(RetainPtr<CGImageRef>&& image, IntSize logicalSize, IntSize internalSize, float resolutionScale, PreserveResolution preserveResolution) >-{ >- if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >- image = createCroppedImageIfNecessary(image.get(), internalSize); >- else { >- auto context = adoptCF(CGBitmapContextCreate(0, logicalSize.width(), logicalSize.height(), 8, 4 * logicalSize.width(), sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast)); >- CGContextSetBlendMode(context.get(), kCGBlendModeCopy); >- CGContextClipToRect(context.get(), FloatRect(FloatPoint::zero(), logicalSize)); >- FloatSize imageSizeInUserSpace = logicalSize; >- CGContextDrawImage(context.get(), FloatRect(FloatPoint::zero(), imageSizeInUserSpace), image.get()); >- image = adoptCF(CGBitmapContextCreateImage(context.get())); >- } >- >- if (!image) >- return nullptr; >- >- return BitmapImage::create(WTFMove(image)); >-} >- >-RefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const >-{ >- RetainPtr<CGImageRef> image; >- if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >- image = copyNativeImage(copyBehavior); >- else >- image = copyNativeImage(DontCopyBackingStore); >- >- return createBitmapImageAfterScalingIfNeeded(WTFMove(image), logicalSize(), internalSize(), m_resolutionScale, preserveResolution); >-} >- >-RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, PreserveResolution preserveResolution) >-{ >- IntSize internalSize = imageBuffer->internalSize(); >- IntSize logicalSize = imageBuffer->logicalSize(); >- float resolutionScale = imageBuffer->m_resolutionScale; >- >- return createBitmapImageAfterScalingIfNeeded(sinkIntoNativeImage(WTFMove(imageBuffer)), logicalSize, internalSize, resolutionScale, preserveResolution); >-} >- >-RetainPtr<CGImageRef> ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer) >-{ >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- if (!imageBuffer->m_data.surface) >- return imageBuffer->copyNativeImage(DontCopyBackingStore); >- >- return IOSurface::sinkIntoImage(IOSurface::createFromImageBuffer(WTFMove(imageBuffer))); >-#else >- return imageBuffer->copyNativeImage(DontCopyBackingStore); >-#endif >-} >- >-RetainPtr<CGImageRef> ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const >-{ >- RetainPtr<CGImageRef> image; >- if (!context().isAcceleratedContext()) { >- switch (copyBehavior) { >- case DontCopyBackingStore: >- image = adoptCF(CGImageCreate(m_data.backingStoreSize.width(), m_data.backingStoreSize.height(), 8, 32, m_data.bytesPerRow.unsafeGet(), m_data.colorSpace, m_data.bitmapInfo, m_data.dataProvider.get(), 0, true, kCGRenderingIntentDefault)); >- break; >- case CopyBackingStore: >- image = adoptCF(CGBitmapContextCreateImage(context().platformContext())); >- break; >- default: >- ASSERT_NOT_REACHED(); >- break; >- } >- } >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- else >- image = m_data.surface->createImage(); >-#endif >- >- return image; >-} >- >-void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >-{ >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- if (!imageBuffer->m_data.surface) { >- imageBuffer->draw(destContext, destRect, srcRect, options); >- return; >- } >- >- ASSERT(destContext.isAcceleratedContext()); >- >- float resolutionScale = imageBuffer->m_resolutionScale; >- IntSize backingStoreSize = imageBuffer->m_data.backingStoreSize; >- >- RetainPtr<CGImageRef> image = IOSurface::sinkIntoImage(IOSurface::createFromImageBuffer(WTFMove(imageBuffer))); >- >- FloatRect adjustedSrcRect = srcRect; >- adjustedSrcRect.scale(resolutionScale); >- destContext.drawNativeImage(image.get(), backingStoreSize, destRect, adjustedSrcRect, options); >-#else >- imageBuffer->draw(destContext, destRect, srcRect, options); >-#endif >-} >- >-void ImageBuffer::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >-{ >- RetainPtr<CGImageRef> image; >- if (&destContext == &context() || destContext.isAcceleratedContext()) >- image = copyNativeImage(CopyBackingStore); // Drawing into our own buffer, need to deep copy. >- else >- image = copyNativeImage(DontCopyBackingStore); >- >- FloatRect adjustedSrcRect = srcRect; >- adjustedSrcRect.scale(m_resolutionScale); >- destContext.drawNativeImage(image.get(), m_data.backingStoreSize, destRect, adjustedSrcRect, options); >-} >- >-void ImageBuffer::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options) >-{ >- FloatRect adjustedSrcRect = srcRect; >- adjustedSrcRect.scale(m_resolutionScale); >- >- if (!context().isAcceleratedContext()) { >- if (&destContext == &context() || destContext.isAcceleratedContext()) { >- if (RefPtr<Image> copy = copyImage(CopyBackingStore)) // Drawing into our own buffer, need to deep copy. >- copy->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >- } else { >- if (RefPtr<Image> imageForRendering = copyImage(DontCopyBackingStore)) >- imageForRendering->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >- } >- } else { >- if (RefPtr<Image> copy = copyImage(CopyBackingStore)) >- copy->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >- } >-} >- >-RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- >- IntRect srcRect = rect; >- if (coordinateSystem == LogicalCoordinateSystem) >- srcRect.scale(m_resolutionScale); >- >- if (pixelArrayDimensions) >- *pixelArrayDimensions = srcRect.size(); >- >- return m_data.getData(AlphaPremultiplication::Unpremultiplied, srcRect, internalSize(), context().isAcceleratedContext()); >-} >- >-RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- >- IntRect srcRect = rect; >- if (coordinateSystem == LogicalCoordinateSystem) >- srcRect.scale(m_resolutionScale); >- >- if (pixelArrayDimensions) >- *pixelArrayDimensions = srcRect.size(); >- >- return m_data.getData(AlphaPremultiplication::Premultiplied, srcRect, internalSize(), context().isAcceleratedContext()); >-} >- >-void ImageBuffer::putByteArray(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem) >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- >- IntRect scaledSourceRect = sourceRect; >- IntSize scaledSourceSize = sourceSize; >- if (coordinateSystem == LogicalCoordinateSystem) { >- scaledSourceRect.scale(m_resolutionScale); >- scaledSourceSize.scale(m_resolutionScale); >- } >- >- m_data.putData(source, sourceFormat, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), context().isAcceleratedContext()); >- >- // Force recreating the IOSurface cached image if it is requested through CGIOSurfaceContextCreateImage(). >- // See https://bugs.webkit.org/show_bug.cgi?id=157966 for explaining why this is necessary. >- if (context().isAcceleratedContext()) >- context().fillRect(FloatRect(1, 1, 0, 0)); >-} >- >-String ImageBuffer::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution preserveResolution) const >-{ >- if (auto data = toCFData(mimeType, quality, preserveResolution)) >- return dataURL(data.get(), mimeType); >- return "data:,"_s; >-} >- >-Vector<uint8_t> ImageBuffer::toData(const String& mimeType, Optional<double> quality) const >-{ >- if (auto data = toCFData(mimeType, quality, PreserveResolution::No)) >- return dataVector(data.get()); >- return { }; >-} >- >-RetainPtr<CFDataRef> ImageBuffer::toCFData(const String& mimeType, Optional<double> quality, PreserveResolution preserveResolution) const >-{ >- ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); >- >- if (context().isAcceleratedContext()) >- flushContext(); >- >- auto uti = utiFromImageBufferMIMEType(mimeType); >- ASSERT(uti); >- >- RetainPtr<CGImageRef> image; >- RefPtr<Uint8ClampedArray> premultipliedData; >- >- if (CFEqual(uti.get(), jpegUTI())) { >- // JPEGs don't have an alpha channel, so we have to manually composite on top of black. >- premultipliedData = getPremultipliedImageData(IntRect(IntPoint(), logicalSize())); >- if (!premultipliedData) >- return nullptr; >- >- size_t dataSize = 4 * logicalSize().width() * logicalSize().height(); >- verifyImageBufferIsBigEnough(premultipliedData->data(), dataSize); >- auto dataProvider = adoptCF(CGDataProviderCreateWithData(nullptr, premultipliedData->data(), dataSize, nullptr)); >- if (!dataProvider) >- return nullptr; >- >- image = adoptCF(CGImageCreate(logicalSize().width(), logicalSize().height(), 8, 32, 4 * logicalSize().width(), sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast, dataProvider.get(), 0, false, kCGRenderingIntentDefault)); >- } else if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) { >- image = copyNativeImage(CopyBackingStore); >- image = createCroppedImageIfNecessary(image.get(), internalSize()); >- } else { >- image = copyNativeImage(DontCopyBackingStore); >- auto context = adoptCF(CGBitmapContextCreate(0, logicalSize().width(), logicalSize().height(), 8, 4 * logicalSize().width(), sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast)); >- CGContextSetBlendMode(context.get(), kCGBlendModeCopy); >- CGContextClipToRect(context.get(), CGRectMake(0, 0, logicalSize().width(), logicalSize().height())); >- FloatSize imageSizeInUserSpace = logicalSize(); >- CGContextDrawImage(context.get(), CGRectMake(0, 0, imageSizeInUserSpace.width(), imageSizeInUserSpace.height()), image.get()); >- image = adoptCF(CGBitmapContextCreateImage(context.get())); >- } >- >- auto cfData = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0)); >- if (!encodeImage(image.get(), uti.get(), quality, cfData.get())) >- return nullptr; >- >- return WTFMove(cfData); >-} >- >-Vector<uint8_t> ImageBuffer::toBGRAData() const >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- return m_data.toBGRAData(context().isAcceleratedContext(), m_size.width(), m_size.height()); >-} >- >-} // namespace WebCore >- >-#endif >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..31cd237581f95d0ccacb82c84fc264f92a79b3eb >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.cpp >@@ -0,0 +1,255 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferCGBackend.h" >+ >+#if USE(CG) >+ >+#include "BitmapImage.h" >+#include "GraphicsContextCG.h" >+#include "ImageBufferUtilitiesCG.h" >+#include "ImageData.h" >+#include "IntRect.h" >+#include "MIMETypeRegistry.h" >+ >+#if USE(ACCELERATE) >+#include <Accelerate/Accelerate.h> >+#endif >+#include <CoreGraphics/CoreGraphics.h> >+#include <pal/spi/cg/CoreGraphicsSPI.h> >+ >+namespace WebCore { >+ >+RetainPtr<CGColorSpaceRef> ImageBufferCGBackend::contextColorSpace(const GraphicsContext& context) >+{ >+#if PLATFORM(COCOA) >+ CGContextRef cgContext = context.platformContext(); >+ >+ if (CGContextGetType(cgContext) == kCGContextTypeBitmap) >+ return CGBitmapContextGetColorSpace(cgContext); >+ >+ return adoptCF(CGContextCopyDeviceColorSpace(cgContext)); >+#else >+ UNUSED_PARAM(context); >+ return nullptr; >+#endif >+} >+# >+ >+void ImageBufferCGBackend::setupContext() >+{ >+ context().scale(FloatSize(1, -1)); >+ context().translate(0, -m_backendSize.height()); >+ context().applyDeviceScaleFactor(m_resolutionScale); >+} >+ >+static RetainPtr<CGImageRef> createCroppedImageIfNecessary(CGImageRef image, const IntSize& backendSize) >+{ >+ if (image && (CGImageGetWidth(image) != static_cast<size_t>(backendSize.width()) || CGImageGetHeight(image) != static_cast<size_t>(backendSize.height()))) >+ return adoptCF(CGImageCreateWithImageInRect(image, CGRectMake(0, 0, backendSize.width(), backendSize.height()))); >+ return image; >+} >+ >+static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(RetainPtr<CGImageRef>&& image, const IntSize& logicalSize, const IntSize& backendSize, float resolutionScale, PreserveResolution preserveResolution) >+{ >+ if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >+ image = createCroppedImageIfNecessary(image.get(), backendSize); >+ else { >+ auto context = adoptCF(CGBitmapContextCreate(0, logicalSize.width(), logicalSize.height(), 8, 4 * logicalSize.width(), sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast)); >+ CGContextSetBlendMode(context.get(), kCGBlendModeCopy); >+ CGContextClipToRect(context.get(), FloatRect(FloatPoint::zero(), logicalSize)); >+ FloatSize imageSizeInUserSpace = logicalSize; >+ CGContextDrawImage(context.get(), FloatRect(FloatPoint::zero(), imageSizeInUserSpace), image.get()); >+ image = adoptCF(CGBitmapContextCreateImage(context.get())); >+ } >+ >+ if (!image) >+ return nullptr; >+ >+ return BitmapImage::create(WTFMove(image)); >+} >+ >+RefPtr<Image> ImageBufferCGBackend::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const >+{ >+ NativeImagePtr image; >+ if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >+ image = copyNativeImage(copyBehavior); >+ else >+ image = copyNativeImage(DontCopyBackingStore); >+ return createBitmapImageAfterScalingIfNeeded(WTFMove(image), m_logicalSize, m_backendSize, m_resolutionScale, preserveResolution); >+} >+ >+RefPtr<Image> ImageBufferCGBackend::sinkIntoImage(PreserveResolution preserveResolution) >+{ >+ return createBitmapImageAfterScalingIfNeeded(sinkIntoNativeImage(), m_logicalSize, m_backendSize, m_resolutionScale, preserveResolution); >+} >+ >+void ImageBufferCGBackend::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >+{ >+ FloatRect srcRectScaled = srcRect; >+ srcRectScaled.scale(m_resolutionScale); >+ >+ if (auto image = copyNativeImage(&destContext == &context() ? CopyBackingStore : DontCopyBackingStore)) >+ destContext.drawNativeImage(image.get(), m_backendSize, destRect, srcRectScaled, options); >+} >+ >+void ImageBufferCGBackend::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options) >+{ >+ FloatRect adjustedSrcRect = srcRect; >+ adjustedSrcRect.scale(m_resolutionScale); >+ >+ if (auto image = copyImage(&destContext == &context() ? CopyBackingStore : DontCopyBackingStore)) >+ image->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >+} >+ >+AffineTransform ImageBufferCGBackend::baseTransform() const >+{ >+ return AffineTransform(1, 0, 0, -1, 0, m_logicalSize.height()); >+} >+ >+RetainPtr<CFDataRef> ImageBufferCGBackend::toCFData(const String& mimeType, Optional<double> quality, PreserveResolution preserveResolution) const >+{ >+ ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); >+ >+ auto uti = utiFromImageBufferMIMEType(mimeType); >+ ASSERT(uti); >+ >+ RetainPtr<CGImageRef> image; >+ RefPtr<Uint8ClampedArray> protectedPixelArray; >+ >+ if (CFEqual(uti.get(), jpegUTI())) { >+ // JPEGs don't have an alpha channel, so we have to manually composite on top of black. >+ auto imageData = getImageData(AlphaPremultiplication::Premultiplied, logicalRect()); >+ if (!imageData) >+ return nullptr; >+ >+ protectedPixelArray = makeRefPtr(imageData->data()); >+ size_t dataSize = protectedPixelArray->byteLength(); >+ IntSize pixelArrayDimensions = imageData->size(); >+ >+ verifyImageBufferIsBigEnough(protectedPixelArray->data(), dataSize); >+ auto dataProvider = adoptCF(CGDataProviderCreateWithData(nullptr, protectedPixelArray->data(), dataSize, nullptr)); >+ if (!dataProvider) >+ return nullptr; >+ >+ image = adoptCF(CGImageCreate(pixelArrayDimensions.width(), pixelArrayDimensions.height(), 8, 32, 4 * pixelArrayDimensions.width(), sRGBColorSpaceRef(), kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast, dataProvider.get(), 0, false, kCGRenderingIntentDefault)); >+ } else if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) { >+ image = copyNativeImage(CopyBackingStore); >+ image = createCroppedImageIfNecessary(image.get(), backendSize()); >+ } else { >+ image = copyNativeImage(DontCopyBackingStore); >+ auto context = adoptCF(CGBitmapContextCreate(0, backendSize().width(), backendSize().height(), 8, 4 * backendSize().width(), sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast)); >+ CGContextSetBlendMode(context.get(), kCGBlendModeCopy); >+ CGContextClipToRect(context.get(), CGRectMake(0, 0, backendSize().width(), backendSize().height())); >+ CGContextDrawImage(context.get(), CGRectMake(0, 0, backendSize().width(), backendSize().height()), image.get()); >+ image = adoptCF(CGBitmapContextCreateImage(context.get())); >+ } >+ >+ auto cfData = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0)); >+ if (!encodeImage(image.get(), uti.get(), quality, cfData.get())) >+ return nullptr; >+ >+ return WTFMove(cfData); >+} >+ >+Vector<uint8_t> ImageBufferCGBackend::toData(const String& mimeType, Optional<double> quality) const >+{ >+ if (auto data = toCFData(mimeType, quality, PreserveResolution::No)) >+ return dataVector(data.get()); >+ return { }; >+} >+ >+String ImageBufferCGBackend::toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution preserveResolution) const >+{ >+ if (auto data = toCFData(mimeType, quality, preserveResolution)) >+ return dataURL(data.get(), mimeType); >+ return "data:,"_s; >+} >+ >+#if USE(ACCELERATE) >+static inline vImage_Buffer makeVImageBuffer(unsigned bytesPerRow, uint8_t* rows, const IntSize& size) >+{ >+ vImage_Buffer vImageBuffer; >+ >+ vImageBuffer.height = static_cast<vImagePixelCount>(size.height()); >+ vImageBuffer.width = static_cast<vImagePixelCount>(size.width()); >+ vImageBuffer.rowBytes = bytesPerRow; >+ vImageBuffer.data = rows; >+ return vImageBuffer; >+} >+ >+static inline void copyImagePixelsAccelerated( >+ AlphaPremultiplication srcAlphaFormat, ColorFormat srcColorFormat, vImage_Buffer& src, >+ AlphaPremultiplication destAlphaFormat, ColorFormat destColorFormat, vImage_Buffer& dest) >+{ >+ if (srcAlphaFormat == destAlphaFormat) { >+ ASSERT(srcColorFormat != destColorFormat); >+ ASSERT(destAlphaFormat == AlphaPremultiplication::Premultiplied); >+ >+ // Swap pixel channels BGRA <-> RGBA. >+ const uint8_t map[4] = { 2, 1, 0, 3 }; >+ vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags); >+ return; >+ } >+ >+ if (destAlphaFormat == AlphaPremultiplication::Unpremultiplied) { >+ if (srcColorFormat == ColorFormat::RGBA) >+ vImageUnpremultiplyData_RGBA8888(&src, &dest, kvImageNoFlags); >+ else >+ vImageUnpremultiplyData_BGRA8888(&src, &dest, kvImageNoFlags); >+ } else { >+ if (srcColorFormat == ColorFormat::RGBA) >+ vImagePremultiplyData_RGBA8888(&src, &dest, kvImageNoFlags); >+ else >+ vImagePremultiplyData_BGRA8888(&src, &dest, kvImageNoFlags); >+ } >+ >+ if (srcColorFormat != destColorFormat) { >+ // Swap pixel channels BGRA <-> RGBA. >+ const uint8_t map[4] = { 2, 1, 0, 3 }; >+ vImagePermuteChannels_ARGB8888(&dest, &dest, map, kvImageNoFlags); >+ } >+} >+ >+void ImageBufferCGBackend::copyImagePixels( >+ AlphaPremultiplication srcAlphaFormat, ColorFormat srcColorFormat, unsigned srcBytesPerRow, uint8_t* srcRows, >+ AlphaPremultiplication destAlphaFormat, ColorFormat destColorFormat, unsigned destBytesPerRow, uint8_t* destRows, const IntSize& size) const >+{ >+ if (srcAlphaFormat == destAlphaFormat && srcColorFormat == destColorFormat) { >+ ImageBufferBackend::copyImagePixels(srcAlphaFormat, srcColorFormat, srcBytesPerRow, srcRows, destAlphaFormat, destColorFormat, destBytesPerRow, destRows, size); >+ return; >+ } >+ >+ vImage_Buffer src = makeVImageBuffer(srcBytesPerRow, srcRows, size); >+ vImage_Buffer dest = makeVImageBuffer(destBytesPerRow, destRows, size); >+ >+ copyImagePixelsAccelerated(srcAlphaFormat, srcColorFormat, src, destAlphaFormat, destColorFormat, dest); >+} >+#endif >+ >+} // namespace WebCore >+ >+#endif // USE(CG) >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.h b/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..c7ca398034f25a3349247d434f5f659f92af3d43 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCGBackend.h >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(CG) >+ >+#include "ImageBufferBackend.h" >+ >+namespace WebCore { >+ >+class WEBCORE_EXPORT ImageBufferCGBackend : public ImageBufferBackend { >+public: >+ RefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore, PreserveResolution = PreserveResolution::No) const override; >+ RefPtr<Image> sinkIntoImage(PreserveResolution) override; >+ >+ void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) override; >+ void drawPattern(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions&) override; >+ >+ AffineTransform baseTransform() const override; >+ >+ String toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const override; >+ Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override; >+ >+protected: >+ using ImageBufferBackend::ImageBufferBackend; >+ >+ static RetainPtr<CGColorSpaceRef> contextColorSpace(const GraphicsContext&); >+ void setupContext(); >+ virtual RetainPtr<CFDataRef> toCFData(const String& mimeType, Optional<double> quality, PreserveResolution) const; >+ >+#if USE(ACCELERATE) >+ void copyImagePixels( >+ AlphaPremultiplication srcAlphaFormat, ColorFormat srcColorFormat, unsigned srcBytesPerRow, uint8_t* srcRows, >+ AlphaPremultiplication destAlphaFormat, ColorFormat destColorFormat, unsigned destBytesPerRow, uint8_t* destRows, const IntSize&) const override; >+#endif >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(CG) >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..9383c996e54d0b04713fdc742c21436d3807e845 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.cpp >@@ -0,0 +1,144 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferCGBitmapBackend.h" >+ >+#if USE(CG) >+ >+#include "GraphicsContext.h" >+#include "GraphicsContextCG.h" >+#include "ImageBufferUtilitiesCG.h" >+#include "ImageData.h" >+#include "IntRect.h" >+#include <wtf/IsoMallocInlines.h> >+ >+namespace WebCore { >+ >+#if PLATFORM(IOS_FAMILY) >+constexpr const CGBitmapInfo DefaultBitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; >+#else >+constexpr const CGBitmapInfo DefaultBitmapInfo = kCGImageAlphaPremultipliedLast; >+#endif >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBufferCGBitmapBackend); >+ >+std::unique_ptr<ImageBufferCGBitmapBackend> ImageBufferCGBitmapBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, CGColorSpaceRef cgColorSpace, const HostWindow*) >+{ >+ IntSize backendSize = calculateBackendSize(size, resolutionScale); >+ if (backendSize.isEmpty()) >+ return nullptr; >+ >+ void* data; >+ unsigned bytesPerRow = 4 * backendSize.width(); >+ >+ if (!tryFastCalloc(backendSize.height(), bytesPerRow).getValue(data)) >+ return nullptr; >+ >+ ASSERT(!(reinterpret_cast<intptr_t>(data) & 3)); >+ >+ size_t numBytes = backendSize.height() * bytesPerRow; >+ verifyImageBufferIsBigEnough(data, numBytes); >+ >+ auto cgContext = adoptCF(CGBitmapContextCreate(data, backendSize.width(), backendSize.height(), 8, bytesPerRow, cgColorSpace, DefaultBitmapInfo)); >+ if (!cgContext) >+ return nullptr; >+ >+ auto context = makeUnique<GraphicsContext>(cgContext.get()); >+ >+ const auto releaseImageData = [] (void*, const void* data, size_t) { >+ fastFree(const_cast<void*>(data)); >+ }; >+ >+ auto dataProvider = adoptCF(CGDataProviderCreateWithData(0, data, numBytes, releaseImageData)); >+ >+ return std::unique_ptr<ImageBufferCGBitmapBackend>(new ImageBufferCGBitmapBackend(size, backendSize, resolutionScale, colorSpace, data, WTFMove(dataProvider), WTFMove(context))); >+} >+ >+std::unique_ptr<ImageBufferCGBitmapBackend> ImageBufferCGBitmapBackend::create(const FloatSize& size, const GraphicsContext& context) >+{ >+ if (auto cgColorSpace = contextColorSpace(context)) >+ return ImageBufferCGBitmapBackend::create(size, 1, ColorSpace::SRGB, cgColorSpace.get(), nullptr); >+ >+ return ImageBufferCGBitmapBackend::create(size, 1, ColorSpace::SRGB, nullptr); >+} >+ >+std::unique_ptr<ImageBufferCGBitmapBackend> ImageBufferCGBitmapBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+{ >+ return ImageBufferCGBitmapBackend::create(size, resolutionScale, colorSpace, cachedCGColorSpace(colorSpace), hostWindow); >+} >+ >+ImageBufferCGBitmapBackend::ImageBufferCGBitmapBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, void* data, RetainPtr<CGDataProviderRef>&& dataProvider, std::unique_ptr<GraphicsContext>&& context) >+ : ImageBufferCGBackend(logicalSize, backendSize, resolutionScale, colorSpace) >+ , m_data(data) >+ , m_dataProvider(WTFMove(dataProvider)) >+ , m_context(WTFMove(context)) >+{ >+ ASSERT(m_data); >+ ASSERT(m_dataProvider); >+ ASSERT(m_context); >+ setupContext(); >+} >+ >+GraphicsContext& ImageBufferCGBitmapBackend::context() const >+{ >+ return *m_context; >+} >+ >+NativeImagePtr ImageBufferCGBitmapBackend::copyNativeImage(BackingStoreCopy copyBehavior) const >+{ >+ switch (copyBehavior) { >+ case CopyBackingStore: >+ return adoptCF(CGBitmapContextCreateImage(context().platformContext())); >+ >+ case DontCopyBackingStore: >+ return adoptCF(CGImageCreate( >+ m_backendSize.width(), m_backendSize.height(), 8, 32, bytesPerRow(), >+ cachedCGColorSpace(m_colorSpace), DefaultBitmapInfo, m_dataProvider.get(), >+ 0, true, kCGRenderingIntentDefault)); >+ } >+ >+ ASSERT_NOT_REACHED(); >+ return nullptr; >+} >+ >+Vector<uint8_t> ImageBufferCGBitmapBackend::toBGRAData() const >+{ >+ return ImageBufferBackend::toBGRAData(m_data); >+} >+ >+RefPtr<ImageData> ImageBufferCGBitmapBackend::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const >+{ >+ return ImageBufferBackend::getImageData(outputFormat, srcRect, m_data); >+} >+ >+void ImageBufferCGBitmapBackend::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint) >+{ >+ ImageBufferBackend::putImageData(inputFormat, imageData, srcRect, destPoint, m_data); >+} >+ >+} // namespace WebCore >+ >+#endif // USE(CG) >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h b/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..b6af662a1c76a8b89b776f2396cb85347d6a491c >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCGBitmapBackend.h >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(CG) >+ >+#include "ImageBufferCGBackend.h" >+#include <wtf/IsoMalloc.h> >+ >+namespace WebCore { >+ >+class ImageBufferCGBitmapBackend : public ImageBufferCGBackend { >+ WTF_MAKE_ISO_ALLOCATED(ImageBufferCGBitmapBackend); >+ WTF_MAKE_NONCOPYABLE(ImageBufferCGBitmapBackend); >+public: >+ static std::unique_ptr<ImageBufferCGBitmapBackend> create(const FloatSize&, float resolutionScale, ColorSpace, CGColorSpaceRef, const HostWindow*); >+ static std::unique_ptr<ImageBufferCGBitmapBackend> create(const FloatSize&, float resolutionScale, ColorSpace, const HostWindow*); >+ static std::unique_ptr<ImageBufferCGBitmapBackend> create(const FloatSize&, const GraphicsContext&); >+ >+ GraphicsContext& context() const override; >+ >+ NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const override; >+ >+ Vector<uint8_t> toBGRAData() const override; >+ >+ RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect&) const override; >+ void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint) override; >+ >+private: >+ ImageBufferCGBitmapBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace, void* data, RetainPtr<CGDataProviderRef>&&, std::unique_ptr<GraphicsContext>&&); >+ >+#if PLATFORM(IOS_FAMILY) >+ ColorFormat backendColorFormat() const override { return ColorFormat::BGRA; } >+#endif >+ >+ void* m_data; >+ RetainPtr<CGDataProviderRef> m_dataProvider; >+ std::unique_ptr<GraphicsContext> m_context; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(CG) >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp >deleted file mode 100644 >index 61fc031cc0664de7a577d1bcb5b4962fdd2eabac..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.cpp >+++ /dev/null >@@ -1,493 +0,0 @@ >-/* >- * Copyright (C) 2011-2017 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ImageBufferData.h" >- >-#if USE(CG) >- >-#include "GraphicsContext.h" >-#include "IntRect.h" >-#include <CoreGraphics/CoreGraphics.h> >-#include <JavaScriptCore/JSCInlines.h> >-#include <JavaScriptCore/TypedArrayInlines.h> >-#include <JavaScriptCore/Uint8ClampedArray.h> >-#include <wtf/Assertions.h> >- >-#if USE(ACCELERATE) >-#include <Accelerate/Accelerate.h> >-#endif >- >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >-#include "IOSurface.h" >-#include <dispatch/dispatch.h> >-#include <pal/spi/cocoa/IOSurfaceSPI.h> >-#endif >- >-// CA uses ARGB32 for textures and ARGB32 -> ARGB32 resampling is optimized. >-#define USE_ARGB32 PLATFORM(IOS_FAMILY) >- >-namespace WebCore { >- >-#if USE(ACCELERATE) && (USE_ARGB32 || USE(IOSURFACE_CANVAS_BACKING_STORE)) >-static void unpremultiplyBufferData(const vImage_Buffer& src, const vImage_Buffer& dest) >-{ >- ASSERT(src.data); >- ASSERT(dest.data); >- >- if (kvImageNoError != vImageUnpremultiplyData_RGBA8888(&src, &dest, kvImageNoFlags)) >- return; >- >- // Swap channels 1 and 3, to convert BGRA<->RGBA. IOSurfaces are BGRA, ImageData expects RGBA. >- const uint8_t map[4] = { 2, 1, 0, 3 }; >- vImagePermuteChannels_ARGB8888(&dest, &dest, map, kvImageNoFlags); >-} >- >-static void premultiplyBufferData(const vImage_Buffer& src, const vImage_Buffer& dest) >-{ >- ASSERT(src.data); >- ASSERT(dest.data); >- >- if (kvImageNoError != vImagePremultiplyData_RGBA8888(&src, &dest, kvImageNoFlags)) >- return; >- >- // Swap channels 1 and 3, to convert BGRA<->RGBA. IOSurfaces are BGRA, ImageData expects RGBA. >- const uint8_t map[4] = { 2, 1, 0, 3 }; >- vImagePermuteChannels_ARGB8888(&dest, &dest, map, kvImageNoFlags); >-} >-#endif // USE(ACCELERATE) && (USE_ARGB32 || USE(IOSURFACE_CANVAS_BACKING_STORE)) >- >-static inline void transferData(void* output, void* input, int width, int height, size_t inputBytesPerRow) >-{ >-#if USE(ACCELERATE) >- ASSERT(input); >- ASSERT(output); >- >- vImage_Buffer src; >- src.width = width; >- src.height = height; >- src.rowBytes = inputBytesPerRow; >- src.data = input; >- >- vImage_Buffer dest; >- dest.width = width; >- dest.height = height; >- dest.rowBytes = width * 4; >- dest.data = output; >- >- vImageUnpremultiplyData_BGRA8888(&src, &dest, kvImageNoFlags); >-#else >- UNUSED_PARAM(output); >- UNUSED_PARAM(input); >- UNUSED_PARAM(width); >- UNUSED_PARAM(height); >- // FIXME: Add support for not ACCELERATE. >- ASSERT_NOT_REACHED(); >-#endif >-} >- >-Vector<uint8_t> ImageBufferData::toBGRAData(bool accelerateRendering, int width, int height) const >-{ >- Vector<uint8_t> result(4 * width * height); >- >- if (!accelerateRendering) { >- transferData(result.data(), data, width, height, 4 * backingStoreSize.width()); >- return result; >- } >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- IOSurface::Locker lock(*surface); >- transferData(result.data(), lock.surfaceBaseAddress(), width, height, surface->bytesPerRow()); >-#else >- ASSERT_NOT_REACHED(); >-#endif >- return result; >-} >- >-RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication outputFormat, const IntRect& rect, const IntSize& size, bool accelerateRendering) const >-{ >- Checked<unsigned, RecordOverflow> area = 4; >- area *= rect.width(); >- area *= rect.height(); >- if (area.hasOverflowed()) >- return nullptr; >- >- auto result = Uint8ClampedArray::tryCreateUninitialized(area.unsafeGet()); >- uint8_t* resultData = result ? result->data() : nullptr; >- if (!resultData) >- return nullptr; >- >- Checked<int> endx = rect.maxX(); >- Checked<int> endy = rect.maxY(); >- if (rect.x() < 0 || rect.y() < 0 || endx.unsafeGet() > size.width() || endy.unsafeGet() > size.height()) >- result->zeroFill(); >- >- int originx = rect.x(); >- int destx = 0; >- Checked<int> destw = rect.width(); >- if (originx < 0) { >- destw += originx; >- destx = -originx; >- originx = 0; >- } >- destw = std::min<int>(destw.unsafeGet(), size.width() - originx); >- if (endx.unsafeGet() > size.width()) >- endx = size.width(); >- Checked<int> width = endx - originx; >- >- int originy = rect.y(); >- int desty = 0; >- Checked<int> desth = rect.height(); >- if (originy < 0) { >- desth += originy; >- desty = -originy; >- originy = 0; >- } >- desth = std::min<int>(desth.unsafeGet(), size.height() - originy); >- if (endy.unsafeGet() > size.height()) >- endy = size.height(); >- Checked<int> height = endy - originy; >- >- if (width.unsafeGet() <= 0 || height.unsafeGet() <= 0) >- return result; >- >- unsigned destBytesPerRow = 4 * rect.width(); >- uint8_t* destRows = resultData + desty * destBytesPerRow + destx * 4; >- >- unsigned srcBytesPerRow; >- uint8_t* srcRows; >- >- if (!accelerateRendering) { >- if (!data) >- return result; >- >- srcBytesPerRow = bytesPerRow.unsafeGet(); >- srcRows = reinterpret_cast<uint8_t*>(data) + originy * srcBytesPerRow + originx * 4; >- >-#if USE(ACCELERATE) >- if (outputFormat == AlphaPremultiplication::Unpremultiplied) { >- >- vImage_Buffer src; >- src.width = width.unsafeGet(); >- src.height = height.unsafeGet(); >- src.rowBytes = srcBytesPerRow; >- src.data = srcRows; >- >- vImage_Buffer dest; >- dest.width = destw.unsafeGet(); >- dest.height = desth.unsafeGet(); >- dest.rowBytes = destBytesPerRow; >- dest.data = destRows; >- >-#if USE_ARGB32 >- unpremultiplyBufferData(src, dest); >-#else >- vImageUnpremultiplyData_RGBA8888(&src, &dest, kvImageNoFlags); >-#endif >- >- return result; >- } >-#endif >- if (outputFormat == AlphaPremultiplication::Unpremultiplied) { >- if ((width * 4).hasOverflowed()) >- CRASH(); >- for (int y = 0; y < height.unsafeGet(); ++y) { >- for (int x = 0; x < width.unsafeGet(); x++) { >- int basex = x * 4; >- uint8_t alpha = srcRows[basex + 3]; >-#if USE_ARGB32 >- // Byte order is different as we use image buffers of ARGB32 >- if (alpha) { >- destRows[basex] = (srcRows[basex + 2] * 255) / alpha; >- destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha; >- destRows[basex + 2] = (srcRows[basex] * 255) / alpha; >- destRows[basex + 3] = alpha; >- } else { >- destRows[basex] = srcRows[basex + 2]; >- destRows[basex + 1] = srcRows[basex + 1]; >- destRows[basex + 2] = srcRows[basex]; >- destRows[basex + 3] = alpha; >- } >-#else >- if (alpha) { >- destRows[basex] = (srcRows[basex] * 255) / alpha; >- destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha; >- destRows[basex + 2] = (srcRows[basex + 2] * 255) / alpha; >- destRows[basex + 3] = alpha; >- } else >- reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<const uint32_t*>(srcRows + basex)[0]; >-#endif >- } >- srcRows += srcBytesPerRow; >- destRows += destBytesPerRow; >- } >- } else { >- for (int y = 0; y < height.unsafeGet(); ++y) { >-#if USE_ARGB32 >- for (int x = 0; x < width.unsafeGet(); x++) { >- int basex = x * 4; >- destRows[basex] = srcRows[basex + 2]; >- destRows[basex + 1] = srcRows[basex + 1]; >- destRows[basex + 2] = srcRows[basex]; >- destRows[basex + 3] = srcRows[basex + 3]; >- } >-#else >- for (int x = 0; x < (width * 4).unsafeGet(); x += 4) >- reinterpret_cast<uint32_t*>(destRows + x)[0] = reinterpret_cast<uint32_t*>(srcRows + x)[0]; >-#endif >- srcRows += srcBytesPerRow; >- destRows += destBytesPerRow; >- } >- } >- } else { >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- IOSurface::Locker lock(*surface); >- srcBytesPerRow = surface->bytesPerRow(); >- srcRows = static_cast<uint8_t*>(lock.surfaceBaseAddress()) + originy * srcBytesPerRow + originx * 4; >- >-#if USE(ACCELERATE) >- vImage_Buffer src; >- src.width = width.unsafeGet(); >- src.height = height.unsafeGet(); >- src.rowBytes = srcBytesPerRow; >- src.data = srcRows; >- >- vImage_Buffer dest; >- dest.width = destw.unsafeGet(); >- dest.height = desth.unsafeGet(); >- dest.rowBytes = destBytesPerRow; >- dest.data = destRows; >- >- if (outputFormat == AlphaPremultiplication::Unpremultiplied) >- unpremultiplyBufferData(src, dest); >- else { >- // Swap pixel channels from BGRA to RGBA. >- const uint8_t map[4] = { 2, 1, 0, 3 }; >- vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags); >- } >-#else >- if ((width * 4).hasOverflowed()) >- CRASH(); >- >- if (outputFormat == AlphaPremultiplication::Unpremultiplied) { >- for (int y = 0; y < height.unsafeGet(); ++y) { >- for (int x = 0; x < width.unsafeGet(); x++) { >- int basex = x * 4; >- uint8_t b = srcRows[basex]; >- uint8_t alpha = srcRows[basex + 3]; >- if (alpha) { >- destRows[basex] = (srcRows[basex + 2] * 255) / alpha; >- destRows[basex + 1] = (srcRows[basex + 1] * 255) / alpha; >- destRows[basex + 2] = (b * 255) / alpha; >- destRows[basex + 3] = alpha; >- } else { >- destRows[basex] = srcRows[basex + 2]; >- destRows[basex + 1] = srcRows[basex + 1]; >- destRows[basex + 2] = b; >- destRows[basex + 3] = srcRows[basex + 3]; >- } >- } >- srcRows += srcBytesPerRow; >- destRows += destBytesPerRow; >- } >- } else { >- for (int y = 0; y < height.unsafeGet(); ++y) { >- for (int x = 0; x < width.unsafeGet(); x++) { >- int basex = x * 4; >- uint8_t b = srcRows[basex]; >- destRows[basex] = srcRows[basex + 2]; >- destRows[basex + 1] = srcRows[basex + 1]; >- destRows[basex + 2] = b; >- destRows[basex + 3] = srcRows[basex + 3]; >- } >- srcRows += srcBytesPerRow; >- destRows += destBytesPerRow; >- } >- } >-#endif // USE(ACCELERATE) >-#else >- ASSERT_NOT_REACHED(); >-#endif // USE(IOSURFACE_CANVAS_BACKING_STORE) >- } >- >- return result; >-} >- >-void ImageBufferData::putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool accelerateRendering) >-{ >- ASSERT(sourceRect.width() > 0); >- ASSERT(sourceRect.height() > 0); >- >- Checked<int> originx = sourceRect.x(); >- Checked<int> destx = (Checked<int>(destPoint.x()) + sourceRect.x()); >- ASSERT(destx.unsafeGet() >= 0); >- ASSERT_UNUSED(size, destx.unsafeGet() < size.width()); >- ASSERT(originx.unsafeGet() >= 0); >- ASSERT(originx.unsafeGet() <= sourceRect.maxX()); >- >- Checked<int> endx = (Checked<int>(destPoint.x()) + sourceRect.maxX()); >- ASSERT(endx.unsafeGet() <= size.width()); >- >- Checked<int> width = sourceRect.width(); >- Checked<int> destw = endx - destx; >- >- Checked<int> originy = sourceRect.y(); >- Checked<int> desty = (Checked<int>(destPoint.y()) + sourceRect.y()); >- ASSERT(desty.unsafeGet() >= 0); >- ASSERT(desty.unsafeGet() < size.height()); >- ASSERT(originy.unsafeGet() >= 0); >- ASSERT(originy.unsafeGet() <= sourceRect.maxY()); >- >- Checked<int> endy = (Checked<int>(destPoint.y()) + sourceRect.maxY()); >- ASSERT(endy.unsafeGet() <= size.height()); >- >- Checked<int> height = sourceRect.height(); >- Checked<int> desth = endy - desty; >- >- if (width <= 0 || height <= 0) >- return; >- >- unsigned srcBytesPerRow = 4 * sourceSize.width(); >- const uint8_t* srcRows = source.data() + (originy * srcBytesPerRow + originx * 4).unsafeGet(); >- unsigned destBytesPerRow; >- uint8_t* destRows; >- >- if (!accelerateRendering) { >- if (!data) >- return; >- >- destBytesPerRow = bytesPerRow.unsafeGet(); >- destRows = reinterpret_cast<uint8_t*>(data) + (desty * destBytesPerRow + destx * 4).unsafeGet(); >- >-#if USE(ACCELERATE) >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied) { >- >- vImage_Buffer src; >- src.width = width.unsafeGet(); >- src.height = height.unsafeGet(); >- src.rowBytes = srcBytesPerRow; >- src.data = const_cast<uint8_t*>(srcRows); >- >- vImage_Buffer dest; >- dest.width = destw.unsafeGet(); >- dest.height = desth.unsafeGet(); >- dest.rowBytes = destBytesPerRow; >- dest.data = destRows; >- >-#if USE_ARGB32 >- premultiplyBufferData(src, dest); >-#else >- vImagePremultiplyData_RGBA8888(&src, &dest, kvImageNoFlags); >-#endif >- return; >- } >-#endif >- >- for (int y = 0; y < height.unsafeGet(); ++y) { >- for (int x = 0; x < width.unsafeGet(); x++) { >- int basex = x * 4; >- uint8_t alpha = srcRows[basex + 3]; >-#if USE_ARGB32 >- // Byte order is different as we use image buffers of ARGB32 >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied && alpha != 255) { >- destRows[basex] = (srcRows[basex + 2] * alpha + 254) / 255; >- destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255; >- destRows[basex + 2] = (srcRows[basex + 0] * alpha + 254) / 255; >- destRows[basex + 3] = alpha; >- } else { >- destRows[basex] = srcRows[basex + 2]; >- destRows[basex + 1] = srcRows[basex + 1]; >- destRows[basex + 2] = srcRows[basex]; >- destRows[basex + 3] = alpha; >- } >-#else >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied && alpha != 255) { >- destRows[basex] = (srcRows[basex] * alpha + 254) / 255; >- destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255; >- destRows[basex + 2] = (srcRows[basex + 2] * alpha + 254) / 255; >- destRows[basex + 3] = alpha; >- } else >- reinterpret_cast<uint32_t*>(destRows + basex)[0] = reinterpret_cast<const uint32_t*>(srcRows + basex)[0]; >-#endif >- } >- destRows += destBytesPerRow; >- srcRows += srcBytesPerRow; >- } >- } else { >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- IOSurface::Locker lock(*surface, IOSurface::Locker::AccessMode::ReadWrite); >- destBytesPerRow = surface->bytesPerRow(); >- destRows = static_cast<uint8_t*>(lock.surfaceBaseAddress()) + (desty * destBytesPerRow + destx * 4).unsafeGet(); >- >-#if USE(ACCELERATE) >- vImage_Buffer src; >- src.width = width.unsafeGet(); >- src.height = height.unsafeGet(); >- src.rowBytes = srcBytesPerRow; >- src.data = const_cast<uint8_t*>(srcRows); >- >- vImage_Buffer dest; >- dest.width = destw.unsafeGet(); >- dest.height = desth.unsafeGet(); >- dest.rowBytes = destBytesPerRow; >- dest.data = destRows; >- >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied) >- premultiplyBufferData(src, dest); >- else { >- // Swap pixel channels from RGBA to BGRA. >- const uint8_t map[4] = { 2, 1, 0, 3 }; >- vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags); >- } >-#else >- for (int y = 0; y < height.unsafeGet(); ++y) { >- for (int x = 0; x < width.unsafeGet(); x++) { >- int basex = x * 4; >- uint8_t b = srcRows[basex]; >- uint8_t alpha = srcRows[basex + 3]; >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied && alpha != 255) { >- destRows[basex] = (srcRows[basex + 2] * alpha + 254) / 255; >- destRows[basex + 1] = (srcRows[basex + 1] * alpha + 254) / 255; >- destRows[basex + 2] = (b * alpha + 254) / 255; >- destRows[basex + 3] = alpha; >- } else { >- destRows[basex] = srcRows[basex + 2]; >- destRows[basex + 1] = srcRows[basex + 1]; >- destRows[basex + 2] = b; >- destRows[basex + 3] = alpha; >- } >- } >- destRows += destBytesPerRow; >- srcRows += srcBytesPerRow; >- } >-#endif // USE(ACCELERATE) >-#else >- ASSERT_NOT_REACHED(); >-#endif // USE(IOSURFACE_CANVAS_BACKING_STORE) >- } >-} >- >-} // namespace WebCore >- >-#endif >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h b/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h >deleted file mode 100644 >index 3e2374bad24f0787fef0543c1b51b9120f1230d4..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/cg/ImageBufferDataCG.h >+++ /dev/null >@@ -1,66 +0,0 @@ >-/* >- * Copyright (C) 2011 Apple Inc. All rights reserved. >- * Copyright (C) 2008 Google Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "AlphaPremultiplication.h" >-#include "Image.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >-#include <wtf/CheckedArithmetic.h> >-#include <wtf/RefPtr.h> >-#include <wtf/RetainPtr.h> >-#include <wtf/Vector.h> >- >-typedef struct CGColorSpace *CGColorSpaceRef; >-typedef struct CGDataProvider *CGDataProviderRef; >-typedef uint32_t CGBitmapInfo; >- >-namespace WebCore { >- >-class IOSurface; >- >-struct ImageBufferData { >- IntSize backingStoreSize; >- Checked<unsigned, RecordOverflow> bytesPerRow; >- CGColorSpaceRef colorSpace; >- >- // Only for software ImageBuffers. >- void* data { nullptr }; >- RetainPtr<CGDataProviderRef> dataProvider; >- CGBitmapInfo bitmapInfo; >- std::unique_ptr<GraphicsContext> context; >- >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- // Only for accelerated ImageBuffers. >- std::unique_ptr<IOSurface> surface; >-#endif >- >- Vector<uint8_t> toBGRAData(bool accelerateRendering, int width, int height) const; >- RefPtr<Uint8ClampedArray> getData(AlphaPremultiplication, const IntRect&, const IntSize&, bool accelerateRendering) const; >- void putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering); >-}; >- >-} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..a47cf5cde639397e7b01547ffddc8b68bd660489 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp >@@ -0,0 +1,180 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferIOSurfaceBackend.h" >+ >+#if HAVE(IOSURFACE) >+ >+#include "GraphicsContextCG.h" >+#include "IOSurface.h" >+#include "ImageData.h" >+#include "IntRect.h" >+#include <CoreGraphics/CoreGraphics.h> >+#include <pal/spi/cg/CoreGraphicsSPI.h> >+#include <wtf/IsoMallocInlines.h> >+ >+namespace WebCore { >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBufferIOSurfaceBackend); >+ >+IntSize ImageBufferIOSurfaceBackend::calculateBackendSize(const FloatSize& size, float resolutionScale) >+{ >+ IntSize backendSize = ImageBufferCGBackend::calculateBackendSize(size, resolutionScale); >+ if (backendSize.isEmpty()) >+ return { }; >+ >+ IntSize maxSize = IOSurface::maximumSize(); >+ if (backendSize.width() > maxSize.width() || backendSize.height() > maxSize.height()) >+ return { }; >+ >+ return backendSize; >+} >+ >+RetainPtr<CGColorSpaceRef> ImageBufferIOSurfaceBackend::contextColorSpace(const GraphicsContext& context) >+{ >+ CGContextRef cgContext = context.platformContext(); >+ >+ if (CGContextGetType(cgContext) == kCGContextTypeIOSurface) >+ return CGIOSurfaceContextGetColorSpace(cgContext); >+ >+ return ImageBufferCGBackend::contextColorSpace(context); >+} >+ >+std::unique_ptr<ImageBufferIOSurfaceBackend> ImageBufferIOSurfaceBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, CGColorSpaceRef cgColorSpace, const HostWindow* hostWindow) >+{ >+ IntSize backendSize = calculateBackendSize(size, resolutionScale); >+ if (backendSize.isEmpty()) >+ return nullptr; >+ >+ auto surface = IOSurface::create(backendSize, backendSize, cgColorSpace); >+ if (!surface) >+ return nullptr; >+ >+ RetainPtr<CGContextRef> cgContext = surface->ensurePlatformContext(hostWindow); >+ if (!cgContext) >+ return nullptr; >+ >+ CGContextClearRect(cgContext.get(), FloatRect(FloatPoint::zero(), backendSize)); >+ >+ return std::unique_ptr<ImageBufferIOSurfaceBackend>(new ImageBufferIOSurfaceBackend(size, backendSize, resolutionScale, colorSpace, WTFMove(surface))); >+} >+ >+std::unique_ptr<ImageBufferIOSurfaceBackend> ImageBufferIOSurfaceBackend::create(const FloatSize& size, const GraphicsContext& context) >+{ >+ if (auto cgColorSpace = contextColorSpace(context)) >+ return ImageBufferIOSurfaceBackend::create(size, 1, ColorSpace::SRGB, cgColorSpace.get(), nullptr); >+ >+ return ImageBufferIOSurfaceBackend::create(size, 1, ColorSpace::SRGB, nullptr); >+} >+ >+std::unique_ptr<ImageBufferIOSurfaceBackend> ImageBufferIOSurfaceBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+{ >+ return ImageBufferIOSurfaceBackend::create(size, resolutionScale, colorSpace, cachedCGColorSpace(colorSpace), hostWindow); >+} >+ >+ >+ImageBufferIOSurfaceBackend::ImageBufferIOSurfaceBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, std::unique_ptr<IOSurface>&& surface) >+ : ImageBufferCGBackend(logicalSize, backendSize, resolutionScale, colorSpace) >+ , m_surface(WTFMove(surface)) >+{ >+ ASSERT(m_surface); >+ setupContext(); >+} >+ >+GraphicsContext& ImageBufferIOSurfaceBackend::context() const >+{ >+ return m_surface->ensureGraphicsContext(); >+} >+ >+void ImageBufferIOSurfaceBackend::flushContext() >+{ >+ CGContextFlush(context().platformContext()); >+} >+ >+size_t ImageBufferIOSurfaceBackend::memoryCost() const >+{ >+ return m_surface->totalBytes(); >+} >+ >+size_t ImageBufferIOSurfaceBackend::externalMemoryCost() const >+{ >+ return memoryCost(); >+} >+ >+unsigned ImageBufferIOSurfaceBackend::bytesPerRow() const >+{ >+ return m_surface->bytesPerRow(); >+} >+ >+ColorFormat ImageBufferIOSurfaceBackend::backendColorFormat() const >+{ >+ return ColorFormat::BGRA; >+} >+ >+NativeImagePtr ImageBufferIOSurfaceBackend::copyNativeImage(BackingStoreCopy) const >+{ >+ return m_surface->createImage(); >+} >+ >+NativeImagePtr ImageBufferIOSurfaceBackend::sinkIntoNativeImage() >+{ >+ return IOSurface::sinkIntoImage(WTFMove(m_surface)); >+} >+ >+void ImageBufferIOSurfaceBackend::drawConsuming(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >+{ >+ FloatRect adjustedSrcRect = srcRect; >+ adjustedSrcRect.scale(m_resolutionScale); >+ >+ if (auto image = sinkIntoNativeImage()) >+ destContext.drawNativeImage(image.get(), m_backendSize, destRect, adjustedSrcRect, options); >+} >+ >+Vector<uint8_t> ImageBufferIOSurfaceBackend::toBGRAData() const >+{ >+ IOSurface::Locker lock(*m_surface); >+ return ImageBufferBackend::toBGRAData(lock.surfaceBaseAddress()); >+} >+ >+RefPtr<ImageData> ImageBufferIOSurfaceBackend::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const >+{ >+ IOSurface::Locker lock(*m_surface); >+ return ImageBufferBackend::getImageData(outputFormat, srcRect, lock.surfaceBaseAddress()); >+} >+ >+void ImageBufferIOSurfaceBackend::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint) >+{ >+ IOSurface::Locker lock(*m_surface, IOSurface::Locker::AccessMode::ReadWrite); >+ ImageBufferBackend::putImageData(inputFormat, imageData, srcRect, destPoint, lock.surfaceBaseAddress()); >+ >+ // Force recreating the IOSurface cached image. >+ // See https://bugs.webkit.org/show_bug.cgi?id=157966 for explaining why this is necessary. >+ context().fillRect(FloatRect(1, 1, 0, 0)); >+} >+ >+} // namespace WebCore >+ >+#endif // HAVE(IOSURFACE) >diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h b/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..dfc0f043f055a77dcef663ee4fc7bf65b96f685f >--- /dev/null >+++ b/Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.h >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if HAVE(IOSURFACE) >+ >+#include "IOSurface.h" >+#include "ImageBufferCGBackend.h" >+#include <wtf/IsoMalloc.h> >+ >+namespace WebCore { >+ >+class WEBCORE_EXPORT ImageBufferIOSurfaceBackend : public ImageBufferCGBackend { >+ WTF_MAKE_ISO_ALLOCATED(ImageBufferIOSurfaceBackend); >+ WTF_MAKE_NONCOPYABLE(ImageBufferIOSurfaceBackend); >+public: >+ static IntSize calculateBackendSize(const FloatSize& logicalSize, float resolutionScale); >+ >+ static std::unique_ptr<ImageBufferIOSurfaceBackend> create(const FloatSize&, float resolutionScale, ColorSpace, CGColorSpaceRef, const HostWindow*); >+ static std::unique_ptr<ImageBufferIOSurfaceBackend> create(const FloatSize&, float resolutionScale, ColorSpace, const HostWindow*); >+ static std::unique_ptr<ImageBufferIOSurfaceBackend> create(const FloatSize&, const GraphicsContext&); >+ >+ GraphicsContext& context() const override; >+ void flushContext() override; >+ >+ size_t memoryCost() const override; >+ size_t externalMemoryCost() const override; >+ >+ NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const override; >+ NativeImagePtr sinkIntoNativeImage() override; >+ >+ void drawConsuming(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions&) override; >+ >+ Vector<uint8_t> toBGRAData() const override; >+ >+ RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect&) const override; >+ void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint) override; >+ >+protected: >+ ImageBufferIOSurfaceBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace, std::unique_ptr<IOSurface>&&); >+ >+ static RetainPtr<CGColorSpaceRef> contextColorSpace(const GraphicsContext&); >+ unsigned bytesPerRow() const override; >+ ColorFormat backendColorFormat() const override; >+ >+ std::unique_ptr<IOSurface> m_surface; >+}; >+ >+} // namespace WebCore >+ >+#endif // HAVE(IOSURFACE) >diff --git a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp >index 2821ef81d75dfb0ff05a85be5c9fbc258b562eb3..2aa82332de2d111bdce1e08063590dce21b6c3e3 100644 >--- a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp >+++ b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.cpp >@@ -254,8 +254,8 @@ void PDFDocumentImage::updateCachedImageIfNeeded(GraphicsContext& context, const > m_cachedSourceRect = srcRect; > ++m_cachingCountForTesting; > >- IntSize internalSize = m_cachedImageBuffer->internalSize(); >- decodedSizeChanged(internalSize.unclampedArea() * 4); >+ IntSize backendSize = m_cachedImageBuffer->backendSize(); >+ decodedSizeChanged(backendSize.unclampedArea() * 4); > } > > ImageDrawResult PDFDocumentImage::draw(GraphicsContext& context, const FloatRect& dstRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >diff --git a/Source/WebCore/platform/graphics/cocoa/IOSurface.mm b/Source/WebCore/platform/graphics/cocoa/IOSurface.mm >index c2125c3ef160c0810109823b4b9036ddf6fbcf67..391fc23cd0a8f869acc10732d14fdf450fc28556 100644 >--- a/Source/WebCore/platform/graphics/cocoa/IOSurface.mm >+++ b/Source/WebCore/platform/graphics/cocoa/IOSurface.mm >@@ -33,7 +33,6 @@ > #import "HostWindow.h" > #import "IOSurfacePool.h" > #import "ImageBuffer.h" >-#import "ImageBufferDataCG.h" > #import "Logging.h" > #import "PlatformScreen.h" > #import <pal/spi/cg/CoreGraphicsSPI.h> >@@ -110,13 +109,6 @@ void IOSurface::moveToPool(std::unique_ptr<IOSurface>&& surface) > IOSurfacePool::sharedPool().addSurface(WTFMove(surface)); > } > >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >-std::unique_ptr<IOSurface> IOSurface::createFromImageBuffer(std::unique_ptr<ImageBuffer> imageBuffer) >-{ >- return WTFMove(imageBuffer->m_data.surface); >-} >-#endif >- > static NSDictionary *optionsForBiplanarSurface(IntSize size, unsigned pixelFormat, size_t firstPlaneBytesPerPixel, size_t secondPlaneBytesPerPixel) > { > int width = size.width(); >diff --git a/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h b/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h >index fd8e5e8e2e94e7054896f9abbba7a46f502141c9..c96e33ca5f6131e52e1e9d45d7c02163de4acc31 100644 >--- a/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h >+++ b/Source/WebCore/platform/graphics/cpu/arm/filters/FEBlendNEON.h >@@ -111,7 +111,8 @@ void FEBlend::platformApplySoftware() > FilterEffect* in = inputEffect(0); > FilterEffect* in2 = inputEffect(1); > >- Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); >+ auto* imageResult = createPremultipliedImageResult(); >+ auto* dstPixelArray = imageResult ? imageResult->data() : nullptr; > if (!dstPixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h b/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1292b1ce48fc44c1815ce774ce1b95c736552ebf >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListDrawingContext.h >@@ -0,0 +1,78 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "AffineTransform.h" >+#include "DisplayList.h" >+#include "DisplayListRecorder.h" >+#include "DisplayListReplayer.h" >+#include "GraphicsContext.h" >+ >+namespace WebCore { >+namespace DisplayList { >+ >+class DrawingContext { >+public: >+ DrawingContext(const FloatSize& logicalSize) >+ : m_context([&](GraphicsContext& displayListContext) { >+ return makeUnique<Recorder>(displayListContext, m_displayList, GraphicsContextState(), FloatRect({ }, logicalSize), AffineTransform()); >+ }) >+ { >+ } >+ >+ GraphicsContext& context() const { return const_cast<DrawingContext&>(*this).m_context; } >+ DisplayList& displayList() { return m_displayList; } >+ const DisplayList& displayList() const { return m_displayList; } >+ const DisplayList* replayDisplayList() const { return m_replayDisplayList.get(); } >+ >+ void setTracksDisplayListReplay(bool tracksDisplayListReplay) >+ { >+ m_tracksDisplayListReplay = tracksDisplayListReplay; >+ m_replayDisplayList.reset(); >+ } >+ >+ void replayDisplayList(GraphicsContext& destContext) >+ { >+ if (!m_displayList.itemCount()) >+ return; >+ >+ Replayer replayer(destContext, m_displayList); >+ if (m_tracksDisplayListReplay) >+ m_replayDisplayList = replayer.replay({ }, m_tracksDisplayListReplay); >+ else >+ replayer.replay(); >+ m_displayList.clear(); >+ } >+ >+private: >+ GraphicsContext m_context; >+ DisplayList m_displayList; >+ std::unique_ptr<DisplayList> m_replayDisplayList; >+ bool m_tracksDisplayListReplay { false }; >+}; >+ >+} // DisplayList >+} // WebCore >diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp >index e6141bde3204c177ab69f51c5d03425a47fc5975..951800eda917411c88b9a4be5514cf1f68c78795 100644 >--- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp >@@ -25,7 +25,7 @@ > > #include "Filter.h" > #include "GraphicsContext.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/MathExtras.h> > #include <wtf/text/TextStream.h> > >@@ -286,13 +286,15 @@ void FEColorMatrix::platformApplySoftware() > resultImage->context().drawImageBuffer(*inBuffer, drawingRegionOfInputImage(in->absolutePaintRect())); > > IntRect imageRect(IntPoint(), resultImage->logicalSize()); >- IntSize pixelArrayDimensions; >- auto pixelArray = resultImage->getUnmultipliedImageData(imageRect, &pixelArrayDimensions); >- if (!pixelArray) >+ auto imageData = resultImage->getImageData(AlphaPremultiplication::Unpremultiplied, imageRect); >+ if (!imageData) > return; > >- Vector<float> values = normalizedFloats(m_values); >+ auto* pixelArray = imageData->data(); >+ IntSize pixelArrayDimensions = imageData->size(); > >+ Vector<float> values = normalizedFloats(m_values); >+ > switch (m_type) { > case FECOLORMATRIX_TYPE_UNKNOWN: > break; >@@ -311,7 +313,7 @@ void FEColorMatrix::platformApplySoftware() > break; > } > >- resultImage->putByteArray(*pixelArray, AlphaPremultiplication::Unpremultiplied, imageRect.size(), imageRect, IntPoint()); >+ resultImage->putImageData(AlphaPremultiplication::Unpremultiplied, *imageData, imageRect); > } > > static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type) >diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp >index fa0413c00da43ac5df55e5e01f6944ab9eda7483..978c55a67b8de720e9fa79bd8cc34d74528a028e 100644 >--- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp >@@ -26,7 +26,7 @@ > > #include "Filter.h" > #include "GraphicsContext.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/MathExtras.h> > #include <wtf/StdLibExtras.h> > #include <wtf/text/TextStream.h> >@@ -108,7 +108,8 @@ void FEComponentTransfer::platformApplySoftware() > { > FilterEffect* in = inputEffect(0); > >- Uint8ClampedArray* pixelArray = createUnmultipliedImageResult(); >+ auto* imageResult = createUnmultipliedImageResult(); >+ auto* pixelArray = imageResult ? imageResult->data() : nullptr; > if (!pixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.cpp b/Source/WebCore/platform/graphics/filters/FEComposite.cpp >index a19ea05375819cecdac25d5d963d544dd4d1a969..265440f43942afa6aa298daf4ec02ee3d95cec80 100644 >--- a/Source/WebCore/platform/graphics/filters/FEComposite.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEComposite.cpp >@@ -27,7 +27,7 @@ > #include "FECompositeArithmeticNEON.h" > #include "Filter.h" > #include "GraphicsContext.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/text/TextStream.h> > > namespace WebCore { >@@ -229,7 +229,8 @@ void FEComposite::platformApplySoftware() > FilterEffect* in2 = inputEffect(1); > > if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) { >- Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); >+ auto* resultImage = createPremultipliedImageResult(); >+ auto* dstPixelArray = resultImage ? resultImage->data() : nullptr; > if (!dstPixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp >index 62c2f833653586844d9f390eea5edc108e30a388..a6e3f4bbaa24497f92634656975ffb87dc7ab9f3 100644 >--- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp >@@ -25,7 +25,7 @@ > #include "FEConvolveMatrix.h" > > #include "Filter.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/ParallelJobs.h> > #include <wtf/WorkQueue.h> > #include <wtf/text/TextStream.h> >@@ -371,12 +371,13 @@ void FEConvolveMatrix::platformApplySoftware() > { > FilterEffect* in = inputEffect(0); > >- Uint8ClampedArray* resultImage; >+ ImageData* resultImage; > if (m_preserveAlpha) > resultImage = createUnmultipliedImageResult(); > else > resultImage = createPremultipliedImageResult(); >- if (!resultImage) >+ auto* dstPixelArray = resultImage ? resultImage->data() : nullptr; >+ if (!dstPixelArray) > return; > > IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); >@@ -395,7 +396,7 @@ void FEConvolveMatrix::platformApplySoftware() > > PaintingData paintingData = { > *srcPixelArray, >- *resultImage, >+ *dstPixelArray, > paintSize.width(), > paintSize.height(), > m_bias * 255, >diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp >index 0e944df00a95cc06d26aa42f169ee6a46f5a2782..5373550453e49862c0e416f2dcc256b470c91951 100644 >--- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp >@@ -27,7 +27,7 @@ > #include "ColorUtilities.h" > #include "Filter.h" > #include "GraphicsContext.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/text/TextStream.h> > > namespace WebCore { >@@ -94,7 +94,8 @@ void FEDisplacementMap::platformApplySoftware() > ASSERT(m_xChannelSelector != CHANNEL_UNKNOWN); > ASSERT(m_yChannelSelector != CHANNEL_UNKNOWN); > >- Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); >+ auto* resultImage = createPremultipliedImageResult(); >+ auto* dstPixelArray = resultImage ? resultImage->data() : nullptr; > if (!dstPixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp b/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp >index 23666a1aef535321493c9ea2d5618e8fddd84ecb..1395a2db85032c9e2ae864c6396668b3741cc331 100644 >--- a/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEDropShadow.cpp >@@ -23,8 +23,8 @@ > #include "FEGaussianBlur.h" > #include "Filter.h" > #include "GraphicsContext.h" >+#include "ImageData.h" > #include "ShadowBlur.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> > #include <wtf/MathExtras.h> > #include <wtf/text/TextStream.h> > >@@ -99,14 +99,15 @@ void FEDropShadow::platformApplySoftware() > ShadowBlur contextShadow(blurRadius, offset, m_shadowColor); > > // TODO: Direct pixel access to ImageBuffer would avoid copying the ImageData. >- IntRect shadowArea(IntPoint(), resultImage->internalSize()); >- auto srcPixelArray = resultImage->getPremultipliedImageData(shadowArea, nullptr, ImageBuffer::BackingStoreCoordinateSystem); >- if (!srcPixelArray) >+ IntRect shadowArea(IntPoint(), resultImage->logicalSize()); >+ auto imageData = resultImage->getImageData(AlphaPremultiplication::Premultiplied, shadowArea); >+ if (!imageData) > return; > >- contextShadow.blurLayerImage(srcPixelArray->data(), shadowArea.size(), 4 * shadowArea.size().width()); >- >- resultImage->putByteArray(*srcPixelArray, AlphaPremultiplication::Premultiplied, shadowArea.size(), shadowArea, IntPoint(), ImageBuffer::BackingStoreCoordinateSystem); >+ auto* srcPixelArray = imageData->data(); >+ contextShadow.blurLayerImage(srcPixelArray->data(), imageData->size(), 4 * imageData->size().width()); >+ >+ resultImage->putImageData(AlphaPremultiplication::Premultiplied, *imageData, shadowArea); > > resultContext.setCompositeOperation(CompositeOperator::SourceIn); > resultContext.fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), m_shadowColor); >diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp >index 49ba84173c2d1a9954e561390ce03c24bc90c81b..d7ed9b24490178ffbfbeb1cd42bea5e8ff159e77 100644 >--- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp >@@ -29,6 +29,7 @@ > #include "FEGaussianBlurNEON.h" > #include "Filter.h" > #include "GraphicsContext.h" >+#include "ImageData.h" > #include <wtf/text/TextStream.h> > > #if USE(ACCELERATE) >@@ -522,14 +523,15 @@ void FEGaussianBlur::platformApplySoftware() > { > FilterEffect* in = inputEffect(0); > >- Uint8ClampedArray* resultPixelArray = createPremultipliedImageResult(); >- if (!resultPixelArray) >+ auto* resultImage = createPremultipliedImageResult(); >+ auto* dstPixelArray = resultImage ? resultImage->data() : nullptr; >+ if (!dstPixelArray) > return; > > setIsAlphaImage(in->isAlphaImage()); > > IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); >- in->copyPremultipliedResult(*resultPixelArray, effectDrawingRect); >+ in->copyPremultipliedResult(*dstPixelArray, effectDrawingRect); > > if (!m_stdX && !m_stdY) > return; >@@ -543,7 +545,7 @@ void FEGaussianBlur::platformApplySoftware() > if (!tmpImageData) > return; > >- platformApply(*resultPixelArray, *tmpImageData, kernelSize.width(), kernelSize.height(), paintSize); >+ platformApply(*dstPixelArray, *tmpImageData, kernelSize.width(), kernelSize.height(), paintSize); > } > > IntOutsets FEGaussianBlur::outsets() const >diff --git a/Source/WebCore/platform/graphics/filters/FELighting.cpp b/Source/WebCore/platform/graphics/filters/FELighting.cpp >index 0ba51b7612f2cb2f69f4f6021cefcbe3c2e742d3..6db87fd545a8f1dda7d9b588a2540655a578fb26 100644 >--- a/Source/WebCore/platform/graphics/filters/FELighting.cpp >+++ b/Source/WebCore/platform/graphics/filters/FELighting.cpp >@@ -30,6 +30,7 @@ > > #include "ColorUtilities.h" > #include "FELightingNEON.h" >+#include "ImageData.h" > #include <wtf/ParallelJobs.h> > > namespace WebCore { >@@ -473,7 +474,8 @@ void FELighting::platformApplySoftware() > { > FilterEffect* in = inputEffect(0); > >- Uint8ClampedArray* resutPixelArray = createPremultipliedImageResult(); >+ auto* resultImage = createPremultipliedImageResult(); >+ auto* resutPixelArray = resultImage ? resultImage->data() : nullptr; > if (!resutPixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp >index 251781ca5aa51f78027ad508df9ac610c6794fa5..cbd4241976570a873945200a913e0e9e659ab425 100644 >--- a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp >+++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp >@@ -27,7 +27,7 @@ > > #include "ColorUtilities.h" > #include "Filter.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/ParallelJobs.h> > #include <wtf/Vector.h> > #include <wtf/text/TextStream.h> >@@ -234,7 +234,8 @@ void FEMorphology::platformApplySoftware() > { > FilterEffect* in = inputEffect(0); > >- Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); >+ auto* resultImage = createPremultipliedImageResult(); >+ auto* dstPixelArray = resultImage ? resultImage->data() : nullptr; > if (!dstPixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp >index 6d60cddebb102f52dc3c21aecc2a50db4bf7834b..f16b9b31a559d74621ff23244da932df43168d49 100644 >--- a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp >+++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp >@@ -27,7 +27,7 @@ > #include "FETurbulence.h" > > #include "Filter.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >+#include "ImageData.h" > #include <wtf/MathExtras.h> > #include <wtf/ParallelJobs.h> > #include <wtf/text/TextStream.h> >@@ -395,7 +395,8 @@ void FETurbulence::fillRegionWorker(FillRegionParameters* parameters) > > void FETurbulence::platformApplySoftware() > { >- Uint8ClampedArray* pixelArray = createUnmultipliedImageResult(); >+ auto* resultImage = createUnmultipliedImageResult(); >+ auto* pixelArray = resultImage ? resultImage->data() : nullptr; > if (!pixelArray) > return; > >diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp >index 6e986d4ec2a9792966384fc55074a2f972b590fa..a9e8fca2c5d1dcbb667a5b7cc0d4f7702484f349 100644 >--- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp >+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp >@@ -27,10 +27,10 @@ > #include "Filter.h" > #include "GeometryUtilities.h" > #include "ImageBuffer.h" >+#include "ImageData.h" > #include "Logging.h" > #include <JavaScriptCore/JSCInlines.h> > #include <JavaScriptCore/TypedArrayInlines.h> >-#include <JavaScriptCore/Uint8ClampedArray.h> > #include <wtf/text/TextStream.h> > > #if HAVE(ARM_NEON_INTRINSICS) >@@ -199,7 +199,7 @@ void FilterEffect::forceValidPreMultipliedPixels() > if (!m_premultipliedImageResult) > return; > >- Uint8ClampedArray* imageArray = m_premultipliedImageResult.get(); >+ Uint8ClampedArray* imageArray = m_premultipliedImageResult->data(); > uint8_t* pixelData = imageArray->data(); > int pixelArrayLength = imageArray->length(); > >@@ -265,7 +265,7 @@ void FilterEffect::clearResultsRecursive() > > ImageBuffer* FilterEffect::imageBufferResult() > { >- LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " imageBufferResult(). Existing image buffer " << m_imageBufferResult.get() << " m_premultipliedImageResult " << m_premultipliedImageResult.get() << " m_unmultipliedImageResult " << m_unmultipliedImageResult.get()); >+ LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " imageBufferResult(). Existing image buffer " << m_imageBufferResult.get() << " m_premultipliedImageResult " << m_premultipliedImageResult->data() << " m_unmultipliedImageResult " << m_unmultipliedImageResult->data()); > > if (!hasResult()) > return nullptr; >@@ -279,9 +279,9 @@ ImageBuffer* FilterEffect::imageBufferResult() > > IntRect destinationRect(IntPoint(), m_absolutePaintRect.size()); > if (m_premultipliedImageResult) >- m_imageBufferResult->putByteArray(*m_premultipliedImageResult, AlphaPremultiplication::Premultiplied, destinationRect.size(), destinationRect, IntPoint()); >+ m_imageBufferResult->putImageData(AlphaPremultiplication::Premultiplied, *m_premultipliedImageResult, destinationRect); > else >- m_imageBufferResult->putByteArray(*m_unmultipliedImageResult, AlphaPremultiplication::Unpremultiplied, destinationRect.size(), destinationRect, IntPoint()); >+ m_imageBufferResult->putImageData(AlphaPremultiplication::Unpremultiplied, *m_unmultipliedImageResult, destinationRect); > return m_imageBufferResult.get(); > } > >@@ -438,52 +438,52 @@ void FilterEffect::copyUnmultipliedResult(Uint8ClampedArray& destination, const > { > ASSERT(hasResult()); > >- LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyUnmultipliedResult(). Existing image buffer " << m_imageBufferResult.get() << " m_premultipliedImageResult " << m_premultipliedImageResult.get() << " m_unmultipliedImageResult " << m_unmultipliedImageResult.get()); >+ LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyUnmultipliedResult(). Existing image buffer " << m_imageBufferResult.get() << " m_premultipliedImageResult " << m_premultipliedImageResult->data() << " m_unmultipliedImageResult " << m_unmultipliedImageResult->data()); > > if (!m_unmultipliedImageResult) { > // We prefer a conversion from the image buffer. > if (m_imageBufferResult) { >- m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size())); >+ m_unmultipliedImageResult = m_imageBufferResult->getImageData(AlphaPremultiplication::Unpremultiplied, { IntPoint(), m_absolutePaintRect.size() }); > if (!m_unmultipliedImageResult) > return; > } else { > IntSize inputSize(m_absolutePaintRect.size()); > ASSERT(!ImageBuffer::sizeNeedsClamping(inputSize)); > inputSize.scale(m_filter.filterScale()); >- m_unmultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((inputSize.area() * 4).unsafeGet()); >+ m_unmultipliedImageResult = ImageData::create(inputSize); > if (!m_unmultipliedImageResult) > return; > >- copyUnpremultiplyingAlpha(*m_premultipliedImageResult, *m_unmultipliedImageResult, inputSize); >+ copyUnpremultiplyingAlpha(*m_premultipliedImageResult->data(), *m_unmultipliedImageResult->data(), inputSize); > } > } >- copyImageBytes(*m_unmultipliedImageResult, destination, rect); >+ copyImageBytes(*m_unmultipliedImageResult->data(), destination, rect); > } > > void FilterEffect::copyPremultipliedResult(Uint8ClampedArray& destination, const IntRect& rect) > { > ASSERT(hasResult()); > >- LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyPremultipliedResult(). Existing image buffer " << m_imageBufferResult.get() << " m_premultipliedImageResult " << m_premultipliedImageResult.get() << " m_unmultipliedImageResult " << m_unmultipliedImageResult.get()); >+ LOG_WITH_STREAM(Filters, stream << "FilterEffect " << filterName() << " " << this << " copyPremultipliedResult(). Existing image buffer " << m_imageBufferResult.get() << " m_premultipliedImageResult " << m_premultipliedImageResult->data() << " m_unmultipliedImageResult " << m_unmultipliedImageResult->data()); > > if (!m_premultipliedImageResult) { > // We prefer a conversion from the image buffer. > if (m_imageBufferResult) { >- m_premultipliedImageResult = m_imageBufferResult->getPremultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size())); >+ m_premultipliedImageResult = m_imageBufferResult->getImageData(AlphaPremultiplication::Premultiplied, { IntPoint(), m_absolutePaintRect.size() }); > if (!m_premultipliedImageResult) > return; > } else { > IntSize inputSize(m_absolutePaintRect.size()); > ASSERT(!ImageBuffer::sizeNeedsClamping(inputSize)); > inputSize.scale(m_filter.filterScale()); >- m_premultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((inputSize.area() * 4).unsafeGet()); >+ m_premultipliedImageResult = ImageData::create(inputSize); > if (!m_premultipliedImageResult) > return; > >- copyPremultiplyingAlpha(*m_unmultipliedImageResult, *m_premultipliedImageResult, inputSize); >+ copyPremultiplyingAlpha(*m_unmultipliedImageResult->data(), *m_premultipliedImageResult->data(), inputSize); > } > } >- copyImageBytes(*m_premultipliedImageResult, destination, rect); >+ copyImageBytes(*m_premultipliedImageResult->data(), destination, rect); > } > > ImageBuffer* FilterEffect::createImageBufferResult() >@@ -497,13 +497,10 @@ ImageBuffer* FilterEffect::createImageBufferResult() > > FloatSize clampedSize = ImageBuffer::clampedSize(m_absolutePaintRect.size()); > m_imageBufferResult = ImageBuffer::create(clampedSize, m_filter.renderingMode(), m_filter.filterScale(), m_resultColorSpace); >- if (!m_imageBufferResult) >- return nullptr; >- > return m_imageBufferResult.get(); > } > >-Uint8ClampedArray* FilterEffect::createUnmultipliedImageResult() >+ImageData* FilterEffect::createUnmultipliedImageResult() > { > LOG(Filters, "FilterEffect %s %p createUnmultipliedImageResult", filterName(), this); > >@@ -515,11 +512,11 @@ Uint8ClampedArray* FilterEffect::createUnmultipliedImageResult() > IntSize resultSize(m_absolutePaintRect.size()); > ASSERT(!ImageBuffer::sizeNeedsClamping(resultSize)); > resultSize.scale(m_filter.filterScale()); >- m_unmultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((resultSize.area() * 4).unsafeGet()); >+ m_unmultipliedImageResult = ImageData::create(resultSize); > return m_unmultipliedImageResult.get(); > } > >-Uint8ClampedArray* FilterEffect::createPremultipliedImageResult() >+ImageData* FilterEffect::createPremultipliedImageResult() > { > LOG(Filters, "FilterEffect %s %p createPremultipliedImageResult", filterName(), this); > >@@ -531,7 +528,7 @@ Uint8ClampedArray* FilterEffect::createPremultipliedImageResult() > IntSize resultSize(m_absolutePaintRect.size()); > ASSERT(!ImageBuffer::sizeNeedsClamping(resultSize)); > resultSize.scale(m_filter.filterScale()); >- m_premultipliedImageResult = Uint8ClampedArray::tryCreateUninitialized((resultSize.area() * 4).unsafeGet()); >+ m_premultipliedImageResult = ImageData::create(resultSize); > return m_premultipliedImageResult.get(); > } > >diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h >index c966fcc21639de5a404a7c62f3ea2b6e9332fe42..af463efeb0136ac618e299cd08d44838d0ef5650 100644 >--- a/Source/WebCore/platform/graphics/filters/FilterEffect.h >+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h >@@ -40,6 +40,7 @@ namespace WebCore { > class Filter; > class FilterEffect; > class ImageBuffer; >+class ImageData; > > typedef Vector<RefPtr<FilterEffect>> FilterEffectVector; > >@@ -153,8 +154,8 @@ protected: > virtual const char* filterName() const = 0; > > ImageBuffer* createImageBufferResult(); >- Uint8ClampedArray* createUnmultipliedImageResult(); >- Uint8ClampedArray* createPremultipliedImageResult(); >+ ImageData* createUnmultipliedImageResult(); >+ ImageData* createPremultipliedImageResult(); > > // Return true if the filter will only operate correctly on valid RGBA values, with > // alpha in [0,255] and each color component in [0, alpha]. >@@ -182,8 +183,8 @@ private: > FilterEffectVector m_inputEffects; > > std::unique_ptr<ImageBuffer> m_imageBufferResult; >- RefPtr<Uint8ClampedArray> m_unmultipliedImageResult; >- RefPtr<Uint8ClampedArray> m_premultipliedImageResult; >+ RefPtr<ImageData> m_unmultipliedImageResult; >+ RefPtr<ImageData> m_premultipliedImageResult; > > IntRect m_absolutePaintRect; > >diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp >index 1e035a7eef2803cf65992d049c9f8b556bcecaec..918e18af5e12ff9049483a78ef1ba82d7358c2a7 100644 >--- a/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp >+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGLCommon.cpp >@@ -188,7 +188,7 @@ void GraphicsContextGLOpenGL::paintRenderingResultsToCanvas(ImageBuffer* imageBu > } > } > >- paintToCanvas(pixels.get(), IntSize(m_currentWidth, m_currentHeight), imageBuffer->internalSize(), imageBuffer->context()); >+ paintToCanvas(pixels.get(), IntSize(m_currentWidth, m_currentHeight), imageBuffer->backendSize(), imageBuffer->context()); > > #if PLATFORM(COCOA) && USE(OPENGL_ES) > presentRenderbuffer(); >diff --git a/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp b/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp >deleted file mode 100644 >index ff1b39415ebb21be6cefac5906f7d4251b83593f..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.cpp >+++ /dev/null >@@ -1,544 +0,0 @@ >-/* >- * Copyright (C) 2016-2019 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ImageBufferData.h" >- >-#if USE(DIRECT2D) >- >-#include "BitmapInfo.h" >-#include "Direct2DUtilities.h" >-#include "GraphicsContext.h" >-#include "HWndDC.h" >-#include "IntRect.h" >-#include "NotImplemented.h" >-#include "PlatformContextDirect2D.h" >-#include <JavaScriptCore/JSCInlines.h> >-#include <JavaScriptCore/TypedArrayInlines.h> >-#include <JavaScriptCore/Uint8ClampedArray.h> >-#include <d2d1.h> >-#include <wtf/Assertions.h> >-#include <wtf/UniqueArray.h> >- >-namespace WebCore { >- >-// Swizzle the red and blue bytes of the pixels in a buffer >-template <AlphaPremultiplication desiredFormat> >-void swizzleAndPremultiply(const uint8_t* srcRows, unsigned rowCount, unsigned colCount, unsigned srcStride, unsigned destStride, uint8_t* destRows) >-{ >- for (unsigned y = 0; y < rowCount; ++y) { >- // Source data may be power-of-two sized, so we need to only copy the bits that >- // correspond to the rectangle supplied by the caller. >- const uint32_t* srcRow = reinterpret_cast<const uint32_t*>(srcRows + srcStride * y); >- uint8_t* destRow = destRows + destStride * y; >- for (unsigned x = 0; x < colCount; ++x) { >- unsigned bytePosition = x * 4; >- const uint32_t* srcPixel = srcRow + x; >- >- // Software filters expect (P)RGBA bytes. We need to swizzle from Direct2D's PBGRA to be compatible. >- uint32_t alpha = (*srcPixel & 0xFF000000) >> 24; >- uint32_t red = (*srcPixel & 0x00FF0000) >> 16; >- uint32_t green = (*srcPixel & 0x0000FF00) >> 8; >- uint32_t blue = (*srcPixel & 0x000000FF); >- >- if (desiredFormat == AlphaPremultiplication::Unpremultiplied) { >- if (alpha && alpha != 255) { >- red = red * 255 / alpha; >- green = green * 255 / alpha; >- blue = blue * 255 / alpha; >- } >- } >- >- destRow[bytePosition] = red; >- destRow[bytePosition + 1] = green; >- destRow[bytePosition + 2] = blue; >- destRow[bytePosition + 3] = alpha; >- } >- } >-} >- >-static bool copyRectFromSourceToDest(const IntRect& sourceRect, const IntSize& sourceBufferSize, const uint8_t* source, const IntSize& destBufferSize, uint8_t* dest, const IntPoint& destBufferPosition) >-{ >- if (!IntRect({ }, destBufferSize).contains(IntRect(destBufferPosition, sourceRect.size()))) >- return false; >- >- if (!IntRect({ }, sourceBufferSize).contains(sourceRect)) >- return false; >- >- unsigned srcStride = sourceBufferSize.width() * 4; >- unsigned destStride = destBufferSize.width() * 4; >- >- unsigned srcRowOffset = sourceRect.location().x() * 4; >- unsigned destRowOffset = destBufferPosition.x() * 4; >- >- const uint8_t* srcRows = source + srcStride * sourceRect.location().y(); >- uint8_t* destRows = dest + destStride * destBufferPosition.y(); >- >- const unsigned bytesPerRow = sourceRect.width() * 4; >- for (unsigned y = 0; y < sourceRect.height(); ++y) { >- const uint8_t* srcRow = srcRows + srcStride * y + srcRowOffset; >- uint8_t* destRow = destRows + destStride * y + destRowOffset; >- memcpy(destRow, srcRow, bytesPerRow); >- } >- >- return true; >-} >- >-// Note: Assumes that bytes are already in RGBA format >-template <AlphaPremultiplication desiredFormat> >-bool copyRectFromSourceToDestAndSetPremultiplication(const IntRect& sourceRect, const IntSize& sourceBufferSize, const uint8_t* source, const IntSize& destBufferSize, uint8_t* dest, const IntPoint& destBufferPosition) >-{ >- if (!IntRect({ }, destBufferSize).contains(IntRect(destBufferPosition, sourceRect.size()))) >- return false; >- >- if (!IntRect({ }, sourceBufferSize).contains(sourceRect)) >- return false; >- >- unsigned srcStride = sourceBufferSize.width() * 4; >- unsigned destStride = destBufferSize.width() * 4; >- >- unsigned srcRowOffset = sourceRect.location().x() * 4; >- unsigned destRowOffset = destBufferPosition.x() * 4; >- >- const uint8_t* srcRows = source + srcStride * sourceRect.location().y(); >- uint8_t* destRows = dest + destStride * destBufferPosition.y(); >- >- const unsigned bytesPerRow = sourceRect.width() * 4; >- for (unsigned y = 0; y < sourceRect.height(); ++y) { >- const uint8_t* srcRow = srcRows + srcStride * y + srcRowOffset; >- uint8_t* destRow = destRows + destStride * y + destRowOffset; >- >- for (size_t x = 0; x < sourceRect.width(); ++x) { >- unsigned pos = x * 4; >- >- unsigned red = srcRow[x]; >- unsigned green = srcRow[x + 1]; >- unsigned blue = srcRow[x + 2]; >- unsigned alpha = srcRow[x + 3]; >- >- if (desiredFormat == AlphaPremultiplication::Premultiplied) { >- if (alpha != 255) { >- red = (red * alpha + 254) / 255; >- green = (green * alpha + 254) / 255; >- blue = (blue * alpha + 254) / 255; >- } >- } else { >- if (alpha && alpha != 255) { >- red = red * 255 / alpha; >- green = green * 255 / alpha; >- blue = blue * 255 / alpha; >- } >- } >- >- uint32_t* pixel = reinterpret_cast<uint32_t*>(destRow) + x; >- *pixel = (alpha << 24) | red << 16 | green << 8 | blue; >- } >- } >- >- return true; >-} >- >-bool ImageBufferData::copyRectFromData(const IntRect& rect, RefPtr<Uint8ClampedArray>& result) const >-{ >- auto rawBitmapSize = bitmap->GetSize(); >- >- float scaleFactor = backingStoreSize.width() / rawBitmapSize.width; >- >- IntRect scaledRect = rect; >- scaledRect.scale(scaleFactor); >- >- if (!IntRect(IntPoint(), backingStoreSize).contains(scaledRect)) { >- // Requested rect is outside the buffer. Return zero-filled buffer. >- result->zeroFill(); >- return true; >- } >- >- return copyRectFromSourceToDest(scaledRect, backingStoreSize, data.data(), rect.size(), result->data(), IntPoint()); >-} >- >-bool ImageBufferData::ensureBackingStore(const IntSize& size) const >-{ >- if (size == backingStoreSize && !data.isEmpty()) >- return true; >- >- auto numBytes = size.area<RecordOverflow>() * 4; >- if (numBytes.hasOverflowed()) >- return false; >- >- backingStoreSize = size; >- data.resizeToFit(numBytes.unsafeGet()); >- return data.capacity() == numBytes.unsafeGet(); >-} >- >-// Swizzle the red and blue bytes of the pixels in a buffer >-template <AlphaPremultiplication sourceFormat> >-void inPlaceSwizzle(uint8_t* byteData, unsigned byteCount) >-{ >- size_t pixelCount = byteCount / 4; >- auto* pixelData = reinterpret_cast<uint32_t*>(byteData); >- >- for (size_t i = 0; i < pixelCount; ++i) { >- uint32_t pixel = *pixelData; >- size_t bytePosition = i * 4; >- >- uint32_t alpha = (pixel & 0xFF000000) >> 24; >- uint32_t red = (pixel & 0x00FF0000) >> 16; >- uint32_t green = (pixel & 0x0000FF00) >> 8; >- uint32_t blue = (pixel & 0x000000FF); >- >- // (P)RGBA -> PBGRA >- if (sourceFormat == AlphaPremultiplication::Unpremultiplied) { >- if (alpha != 255) { >- red = (red * alpha + 254) / 255; >- green = (green * alpha + 254) / 255; >- blue = (blue * alpha + 254) / 255; >- } >- } >- >- *pixelData = (alpha << 24) | red << 16 | green << 8 | blue; >- ++pixelData; >- } >-} >- >-// Note: Assumes that bytes are already in RGBA format >-template <AlphaPremultiplication desiredFormat> >-void inPlaceChangePremultiplication(uint8_t* byteData, unsigned byteCount) >-{ >- size_t pixelCount = byteCount / 4; >- >- for (size_t i = 0; i < pixelCount; ++i) { >- unsigned x = pixelCount * 4; >- >- unsigned red = byteData[x]; >- unsigned green = byteData[x + 1]; >- unsigned blue = byteData[x + 2]; >- unsigned alpha = byteData[x + 3]; >- >- if (desiredFormat == AlphaPremultiplication::Premultiplied) { >- if (alpha != 255) { >- red = (red * alpha + 254) / 255; >- green = (green * alpha + 254) / 255; >- blue = (blue * alpha + 254) / 255; >- } >- } else { >- if (alpha && alpha != 255) { >- red = red * 255 / alpha; >- green = green * 255 / alpha; >- blue = blue * 255 / alpha; >- } >- } >- >- uint32_t* pixel = reinterpret_cast<uint32_t*>(byteData) + i; >- *pixel = (alpha << 24) | red << 16 | green << 8 | blue; >- } >-} >- >-RefPtr<Uint8ClampedArray> ImageBufferData::getData(AlphaPremultiplication desiredFormat, const IntRect& rect, const IntSize& size, bool /* accelerateRendering */, float /* resolutionScale */) const >-{ >- auto numBytes = rect.area<RecordOverflow>() * 4; >- if (numBytes.hasOverflowed()) >- return nullptr; >- >- auto result = Uint8ClampedArray::tryCreateUninitialized(numBytes.unsafeGet()); >- if (!result) >- return nullptr; >- >- if (!bitmap) >- return result; >- >- if (!readDataFromBitmapIfNeeded(desiredFormat)) >- return nullptr; >- >- auto rawBitmapSize = bitmap->GetSize(); >- IntSize bitmapSize(clampTo<int>(rawBitmapSize.width), clampTo<int>(rawBitmapSize.height)); >- >- if (rect.location() == IntPoint() && rect.size() == bitmapSize) { >- RELEASE_ASSERT(numBytes.unsafeGet() == data.size()); >- result->setRange(data.data(), data.size(), 0); >- } else { >- // Only want part of the bitmap. >- if (!copyRectFromData(rect, result)) >- return nullptr; >- } >- >- if (byteFormat != desiredFormat) { >- // In-memory data does not match desired format. Need to swizzle the results. >- if (desiredFormat == AlphaPremultiplication::Unpremultiplied) >- inPlaceChangePremultiplication<AlphaPremultiplication::Unpremultiplied>(result->data(), result->length()); >- else >- inPlaceChangePremultiplication<AlphaPremultiplication::Premultiplied>(result->data(), result->length()); >- } >- >- return result; >-} >- >-bool ImageBufferData::readDataFromBitmapIfNeeded(AlphaPremultiplication desiredFormat) const >-{ >- if (bitmapBufferSync != BitmapBufferSync::BufferOutOfSync) >- return true; >- >- IntSize pixelSize = bitmap->GetPixelSize(); >- >- auto numBytes = pixelSize.area<RecordOverflow>() * 4; >- if (numBytes.hasOverflowed()) >- return false; >- >- context->endDraw(); >- >- COMPtr<ID2D1DeviceContext> d2dDeviceContext = platformContext->deviceContext(); >- ASSERT(!!d2dDeviceContext); >- >- auto bytesPerRowInData = pixelSize.width() * 4; >- >- // Copy GPU data from the ID2D1Bitmap to a CPU-backed ID2D1Bitmap1 >- COMPtr<ID2D1Bitmap1> cpuBitmap; >- D2D1_BITMAP_PROPERTIES1 bitmapProperties2 = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat()); >- HRESULT hr = d2dDeviceContext->CreateBitmap(pixelSize, nullptr, bytesPerRowInData, bitmapProperties2, &cpuBitmap); >- if (!SUCCEEDED(hr)) >- return false; >- >- auto targetPos = D2D1::Point2U(); >- D2D1_RECT_U dataRect = D2D1::RectU(0, 0, pixelSize.width(), pixelSize.height()); >- hr = cpuBitmap->CopyFromBitmap(&targetPos, bitmap.get(), &dataRect); >- if (!SUCCEEDED(hr)) >- return false; >- >- D2D1_MAPPED_RECT mappedData; >- hr = cpuBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedData); >- if (!SUCCEEDED(hr)) >- return false; >- >- if (!mappedData.bits) >- return false; >- >- if (!ensureBackingStore(pixelSize)) >- return false; >- >- // Software filters expect RGBA bytes. We need to swizzle from Direct2D's BGRA to be compatible. >- if (desiredFormat == AlphaPremultiplication::Premultiplied) >- swizzleAndPremultiply<AlphaPremultiplication::Premultiplied>(mappedData.bits, pixelSize.height(), pixelSize.width(), mappedData.pitch, bytesPerRowInData, data.data()); >- else >- swizzleAndPremultiply<AlphaPremultiplication::Unpremultiplied>(mappedData.bits, pixelSize.height(), pixelSize.width(), mappedData.pitch, bytesPerRowInData, data.data()); >- >- byteFormat = desiredFormat; >- >- bitmapBufferSync = BitmapBufferSync::InSync; >- >- hr = cpuBitmap->Unmap(); >- ASSERT(SUCCEEDED(hr)); >- >- context->beginDraw(); >- >- return true; >-} >- >-void ImageBufferData::putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize& size, bool /* accelerateRendering */, float resolutionScale) >-{ >- ASSERT(sourceRect.width() > 0); >- ASSERT(sourceRect.height() > 0); >- >- Checked<int> originx = sourceRect.x(); >- Checked<int> destx = (Checked<int>(destPoint.x()) + sourceRect.x()); >- destx *= resolutionScale; >- ASSERT(destx.unsafeGet() >= 0); >- ASSERT(destx.unsafeGet() < size.width()); >- ASSERT(originx.unsafeGet() >= 0); >- ASSERT(originx.unsafeGet() <= sourceRect.maxX()); >- >- Checked<int> endx = (Checked<int>(destPoint.x()) + sourceRect.maxX()); >- endx *= resolutionScale; >- ASSERT(endx.unsafeGet() <= size.width()); >- >- Checked<int> width = sourceRect.width(); >- Checked<int> destw = endx - destx; >- >- Checked<int> originy = sourceRect.y(); >- Checked<int> desty = (Checked<int>(destPoint.y()) + sourceRect.y()); >- desty *= resolutionScale; >- ASSERT(desty.unsafeGet() >= 0); >- ASSERT(desty.unsafeGet() < size.height()); >- ASSERT(originy.unsafeGet() >= 0); >- ASSERT(originy.unsafeGet() <= sourceRect.maxY()); >- >- Checked<int> endy = (Checked<int>(destPoint.y()) + sourceRect.maxY()); >- endy *= resolutionScale; >- ASSERT(endy.unsafeGet() <= size.height()); >- >- Checked<int> height = sourceRect.height(); >- Checked<int> desth = endy - desty; >- >- if (width <= 0 || height <= 0) >- return; >- >-#if ASSERT_ENABLED >- if (bitmap) { >- auto pixelSize = bitmap->GetPixelSize(); >- ASSERT(pixelSize.width >= sourceSize.width()); >- ASSERT(pixelSize.width >= size.width()); >- ASSERT(pixelSize.height >= sourceSize.height()); >- ASSERT(pixelSize.height >= size.height()); >- } >-#endif >- >- if (!ensureBackingStore(size)) >- return; >- >- if (sourceSize == size) { >- memcpy(data.data(), source.data(), source.length()); >- byteFormat = sourceFormat; >- } else { >- readDataFromBitmapIfNeeded(byteFormat); >- if (!copyRectFromSourceToData(sourceRect, source, sourceFormat)) >- return; >- } >- >- bitmapBufferSync = BitmapBufferSync::BitmapOutOfSync; >-} >- >-bool ImageBufferData::copyRectFromSourceToData(const IntRect& sourceRect, const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat) >-{ >- IntSize pixelSize = bitmap->GetPixelSize(); >- >- IntRect sourceRectToCopy = sourceRect; >- if (!IntRect(IntPoint(), pixelSize).contains(sourceRect)) >- return false; >- >- auto destBufferPosition = sourceRect.location(); >- >- if (sourceFormat == byteFormat) >- return copyRectFromSourceToDest(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition); >- >- if (byteFormat == AlphaPremultiplication::Unpremultiplied) >- return copyRectFromSourceToDestAndSetPremultiplication<AlphaPremultiplication::Unpremultiplied>(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition); >- >- return copyRectFromSourceToDestAndSetPremultiplication<AlphaPremultiplication::Premultiplied>(sourceRect, sourceRect.size(), source.data(), backingStoreSize, data.data(), destBufferPosition); >-} >- >-void ImageBufferData::loadDataToBitmapIfNeeded() >-{ >- if (bitmapBufferSync != BitmapBufferSync::BitmapOutOfSync || data.isEmpty()) >- return; >- >- auto pixelSize = bitmap->GetPixelSize(); >- ASSERT(pixelSize.width >= backingStoreSize.width()); >- ASSERT(pixelSize.height >= backingStoreSize.height()); >- >- Checked<unsigned, RecordOverflow> numBytes = pixelSize.width * pixelSize.height * 4; >- if (numBytes.hasOverflowed()) >- return; >- >- // Software generated bitmap data is in RGBA. We need to swizzle to premultiplied BGRA to be compatible >- // with the HWND/HDC render backing we use. >- if (byteFormat == AlphaPremultiplication::Unpremultiplied) >- inPlaceSwizzle<AlphaPremultiplication::Unpremultiplied>(data.data(), data.size()); // RGBA -> PBGRA >- else >- inPlaceSwizzle<AlphaPremultiplication::Premultiplied>(data.data(), data.size()); // PRGBA -> PBGRA >- >- auto bytesPerRowInData = backingStoreSize.width() * 4; >- >- HRESULT hr = bitmap->CopyFromMemory(nullptr, data.data(), bytesPerRowInData); >- ASSERT(SUCCEEDED(hr)); >- >- bitmapBufferSync = BitmapBufferSync::InSync; >-} >- >-COMPtr<ID2D1Bitmap> ImageBufferData::compatibleBitmap(ID2D1RenderTarget* renderTarget) >-{ >- loadDataToBitmapIfNeeded(); >- >- if (!renderTarget) >- return bitmap; >- >- if (platformContext->renderTarget() == renderTarget) { >- COMPtr<ID2D1BitmapRenderTarget> bitmapTarget(Query, renderTarget); >- if (bitmapTarget) { >- COMPtr<ID2D1Bitmap> backingBitmap; >- if (SUCCEEDED(bitmapTarget->GetBitmap(&backingBitmap))) { >- if (backingBitmap != bitmap) >- return bitmap; >- >- // We can't draw an ID2D1Bitmap to itself. Must return a copy. >- COMPtr<ID2D1Bitmap> copiedBitmap; >- if (SUCCEEDED(renderTarget->CreateBitmap(bitmap->GetPixelSize(), Direct2D::bitmapProperties(), &copiedBitmap))) { >- if (SUCCEEDED(copiedBitmap->CopyFromBitmap(nullptr, bitmap.get(), nullptr))) >- return copiedBitmap; >- } >- } >- } >- } >- >- auto size = bitmap->GetPixelSize(); >- ASSERT(size.height && size.width); >- >- Checked<unsigned, RecordOverflow> numBytes = size.width * size.height * 4; >- if (numBytes.hasOverflowed()) >- return nullptr; >- >- // Copy the bits from current renderTarget to the output target. >- // We cannot access the data backing an IWICBitmap while an active draw session is open. >- context->endDraw(); >- >- COMPtr<ID2D1DeviceContext> sourceDeviceContext = platformContext->deviceContext(); >- if (!sourceDeviceContext) >- return nullptr; >- >- COMPtr<ID2D1Bitmap1> sourceCPUBitmap; >- D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat()); >- HRESULT hr = sourceDeviceContext->CreateBitmap(bitmap->GetPixelSize(), nullptr, bytesPerRow.unsafeGet(), bitmapProperties, &sourceCPUBitmap); >- if (!SUCCEEDED(hr)) >- return nullptr; >- >- if (!sourceCPUBitmap) >- return nullptr; >- >- hr = sourceCPUBitmap->CopyFromBitmap(nullptr, bitmap.get(), nullptr); >- if (!SUCCEEDED(hr)) >- return nullptr; >- >- D2D1_MAPPED_RECT mappedSourceData; >- hr = sourceCPUBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedSourceData); >- if (!SUCCEEDED(hr)) >- return nullptr; >- >- COMPtr<ID2D1DeviceContext> targetDeviceContext; >- hr = renderTarget->QueryInterface(&targetDeviceContext); >- ASSERT(SUCCEEDED(hr)); >- >- COMPtr<ID2D1Bitmap> compatibleBitmap; >- hr = targetDeviceContext->CreateBitmap(bitmap->GetPixelSize(), mappedSourceData.bits, mappedSourceData.pitch, Direct2D::bitmapProperties(), &compatibleBitmap); >- if (!SUCCEEDED(hr)) >- return nullptr; >- >- hr = sourceCPUBitmap->Unmap(); >- ASSERT(SUCCEEDED(hr)); >- >- context->beginDraw(); >- >- return compatibleBitmap; >-} >- >-} // namespace WebCore >- >-#endif >diff --git a/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h b/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h >deleted file mode 100644 >index 9c94d8a4822f125f406f3007747ff9358c156a30..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/win/ImageBufferDataDirect2D.h >+++ /dev/null >@@ -1,70 +0,0 @@ >-/* >- * Copyright (C) 2016-2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#include "Image.h" >-#include "IntSize.h" >-#include "PlatformContextDirect2D.h" >-#include <JavaScriptCore/Uint8ClampedArray.h> >-#include <wtf/CheckedArithmetic.h> >-#include <wtf/RefPtr.h> >-#include <wtf/RetainPtr.h> >- >-interface ID2D1RenderTarget; >-interface ID2D1Bitmap; >- >-namespace WebCore { >- >-class PlatformContextDirect2D; >- >-struct ImageBufferData { >- mutable IntSize backingStoreSize; >- Checked<unsigned, RecordOverflow> bytesPerRow; >- >- // Only for software ImageBuffers. >- mutable Vector<uint8_t> data; >- mutable AlphaPremultiplication byteFormat { AlphaPremultiplication::Unpremultiplied }; >- std::unique_ptr<PlatformContextDirect2D> platformContext; >- std::unique_ptr<GraphicsContext> context; >- COMPtr<ID2D1Bitmap> bitmap; >- >- enum class BitmapBufferSync { InSync, BitmapOutOfSync, BufferOutOfSync }; >- mutable BitmapBufferSync bitmapBufferSync { BitmapBufferSync::BufferOutOfSync }; >- >- RefPtr<Uint8ClampedArray> getData(AlphaPremultiplication, const IntRect&, const IntSize&, bool accelerateRendering, float resolutionScale) const; >- void putData(const Uint8ClampedArray& source, AlphaPremultiplication sourceFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, const IntSize&, bool accelerateRendering, float resolutionScale); >- >- COMPtr<ID2D1Bitmap> compatibleBitmap(ID2D1RenderTarget*); >- >- bool ensureBackingStore(const IntSize&) const; >- void loadDataToBitmapIfNeeded(); >- bool readDataFromBitmapIfNeeded(AlphaPremultiplication desiredFormat) const; >- bool copyRectFromData(const IntRect&, RefPtr<Uint8ClampedArray>&) const; >- bool copyRectFromSourceToData(const IntRect&, const Uint8ClampedArray&, AlphaPremultiplication); >- void markBufferOutOfSync() { bitmapBufferSync = BitmapBufferSync::BufferOutOfSync; } >-}; >- >-} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp b/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp >deleted file mode 100644 >index e04218f1ef4f578ce07f94b7a8ecbb830a5267f9..0000000000000000000000000000000000000000 >--- a/Source/WebCore/platform/graphics/win/ImageBufferDirect2D.cpp >+++ /dev/null >@@ -1,351 +0,0 @@ >-/* >- * Copyright (C) 2016-2019 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "ImageBuffer.h" >- >-#if USE(DIRECT2D) >- >-#include "BitmapImage.h" >-#include "COMPtr.h" >-#include "Direct2DUtilities.h" >-#include "GraphicsContext.h" >-#include "ImageData.h" >-#include "ImageDecoderDirect2D.h" >-#include "IntRect.h" >-#include "MIMETypeRegistry.h" >-#include "NotImplemented.h" >-#include "PlatformContextDirect2D.h" >-#include <d2d1_1.h> >-#include <math.h> >-#include <wincodec.h> >-#include <wtf/Assertions.h> >-#include <wtf/CheckedArithmetic.h> >-#include <wtf/MainThread.h> >-#include <wtf/RetainPtr.h> >-#include <wtf/text/Base64.h> >-#include <wtf/text/WTFString.h> >- >- >-namespace WebCore { >- >-std::unique_ptr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const FloatSize& size, const GraphicsContext& context) >-{ >- if (size.isEmpty()) >- return nullptr; >- >- RenderingMode renderingMode = context.renderingMode(); >- IntSize scaledSize = ImageBuffer::compatibleBufferSize(size, context); >- bool success = false; >- std::unique_ptr<ImageBuffer> buffer(new ImageBuffer(scaledSize, 1, ColorSpace::SRGB, renderingMode, nullptr, &context, success)); >- >- if (!success) >- return nullptr; >- >- // Set up a corresponding scale factor on the graphics context. >- buffer->context().scale(FloatSize(scaledSize.width() / size.width(), scaledSize.height() / size.height())); >- return buffer; >-} >- >-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace /*colorSpace*/, RenderingMode renderingMode, const HostWindow*, const GraphicsContext* targetContext, bool& success) >- : m_logicalSize(size) >- , m_resolutionScale(resolutionScale) >-{ >- success = false; // Make early return mean failure. >- float scaledWidth = std::ceil(resolutionScale * size.width()); >- float scaledHeight = std::ceil(resolutionScale * size.height()); >- >- // FIXME: Should we automatically use a lower resolution? >- if (!FloatSize(scaledWidth, scaledHeight).isExpressibleAsIntSize()) >- return; >- >- m_size = IntSize(scaledWidth, scaledHeight); >- m_data.backingStoreSize = m_size; >- >- bool accelerateRendering = renderingMode == RenderingMode::Accelerated; >- if (m_size.width() <= 0 || m_size.height() <= 0) >- return; >- >- // Prevent integer overflows >- m_data.bytesPerRow = 4 * Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.width()); >- Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.height()) * m_data.bytesPerRow; >- if (numBytes.hasOverflowed()) >- return; >- >- auto* platformContext = targetContext ? targetContext->platformContext() : nullptr; >- auto* renderTarget = platformContext ? platformContext->renderTarget() : nullptr; >- >- if (!renderTarget) >- renderTarget = GraphicsContext::defaultRenderTarget(); >- >- auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(m_logicalSize, renderTarget, m_resolutionScale); >- if (!bitmapContext) >- return; >- >- HRESULT hr = bitmapContext->GetBitmap(&m_data.bitmap); >- if (!SUCCEEDED(hr)) >- return; >- >- m_data.platformContext = makeUnique<PlatformContextDirect2D>(bitmapContext.get(), [this]() { >- m_data.loadDataToBitmapIfNeeded(); >- }, [this]() { >- m_data.markBufferOutOfSync(); >- }); >- m_data.context = makeUnique<GraphicsContext>(m_data.platformContext.get(), GraphicsContext::BitmapRenderingContextType::GPUMemory); >- >- success = true; >-} >- >-ImageBuffer::ImageBuffer(const FloatSize& size, float resolutionScale, ColorSpace imageColorSpace, RenderingMode renderingMode, const HostWindow*, bool& success) >- : ImageBuffer(size, resolutionScale, imageColorSpace, renderingMode, nullptr, nullptr, success) >-{ >-} >- >-ImageBuffer::~ImageBuffer() = default; >- >-GraphicsContext& ImageBuffer::context() const >-{ >- return *m_data.context; >-} >- >-void ImageBuffer::flushContext() const >-{ >- context().flush(); >-} >- >-static COMPtr<ID2D1Bitmap> createCroppedImageIfNecessary(ID2D1BitmapRenderTarget* bitmapTarget, ID2D1Bitmap* image, const IntSize& bounds) >-{ >- FloatSize imageSize = image ? nativeImageSize(image) : FloatSize(); >- >- if (image && (static_cast<size_t>(imageSize.width()) != static_cast<size_t>(bounds.width()) || static_cast<size_t>(imageSize.height()) != static_cast<size_t>(bounds.height()))) { >- COMPtr<ID2D1Bitmap> croppedBitmap = Direct2D::createBitmap(bitmapTarget, bounds); >- if (croppedBitmap) { >- auto sourceRect = D2D1::RectU(0, 0, bounds.width(), bounds.height()); >- HRESULT hr = croppedBitmap->CopyFromBitmap(nullptr, image, &sourceRect); >- if (SUCCEEDED(hr)) >- return croppedBitmap; >- } >- } >- >- return image; >-} >- >-static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(ID2D1BitmapRenderTarget* bitmapTarget, COMPtr<ID2D1Bitmap>&& image, IntSize internalSize, IntSize logicalSize, IntSize backingStoreSize, float resolutionScale, PreserveResolution preserveResolution) >-{ >- if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >- image = createCroppedImageIfNecessary(bitmapTarget, image.get(), internalSize); >- else { >- // FIXME: Need to implement scaled version >- notImplemented(); >- } >- >- if (!image) >- return nullptr; >- >- return BitmapImage::create(WTFMove(image)); >-} >- >-RefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const >-{ >- COMPtr<ID2D1Bitmap> image; >- if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >- image = copyNativeImage(copyBehavior); >- else >- image = copyNativeImage(DontCopyBackingStore); >- >- auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext()); >- return createBitmapImageAfterScalingIfNeeded(bitmapTarget, WTFMove(image), internalSize(), logicalSize(), m_data.backingStoreSize, m_resolutionScale, preserveResolution); >-} >- >-RefPtr<Image> ImageBuffer::sinkIntoImage(std::unique_ptr<ImageBuffer> imageBuffer, PreserveResolution preserveResolution) >-{ >- IntSize internalSize = imageBuffer->internalSize(); >- IntSize logicalSize = imageBuffer->logicalSize(); >- IntSize backingStoreSize = imageBuffer->m_data.backingStoreSize; >- float resolutionScale = imageBuffer->m_resolutionScale; >- >- COMPtr<ID2D1BitmapRenderTarget> bitmapTarget; >- HRESULT hr = imageBuffer->context().platformContext()->renderTarget()->QueryInterface(&bitmapTarget); >- if (!SUCCEEDED(hr)) >- return nullptr; >- >- return createBitmapImageAfterScalingIfNeeded(bitmapTarget.get(), sinkIntoNativeImage(WTFMove(imageBuffer)), internalSize, logicalSize, backingStoreSize, resolutionScale, preserveResolution); >-} >- >-COMPtr<ID2D1Bitmap> ImageBuffer::sinkIntoNativeImage(std::unique_ptr<ImageBuffer> imageBuffer) >-{ >- // FIXME: See if we can reuse the on-hardware image. >- return imageBuffer->copyNativeImage(DontCopyBackingStore); >-} >- >-COMPtr<ID2D1Bitmap> ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const >-{ >- COMPtr<ID2D1BitmapRenderTarget> bitmapTarget; >- HRESULT hr = context().platformContext()->renderTarget()->QueryInterface(&bitmapTarget); >- if (!SUCCEEDED(hr)) >- return nullptr; >- >- COMPtr<ID2D1Bitmap> image; >- hr = bitmapTarget->GetBitmap(&image); >- ASSERT(SUCCEEDED(hr)); >- >- // FIXME: m_data.data is nullptr even when asking to copy backing store leading to test failures. >- if (copyBehavior == CopyBackingStore && m_data.data.isEmpty()) >- copyBehavior = DontCopyBackingStore; >- >- Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.height()) * m_data.bytesPerRow; >- if (numBytes.hasOverflowed()) >- return nullptr; >- >- if (!context().isAcceleratedContext()) { >- switch (copyBehavior) { >- case DontCopyBackingStore: >- break; >- case CopyBackingStore: >- D2D1_RECT_U backingStoreDimenstions = IntRect(IntPoint(), m_data.backingStoreSize); >- image->CopyFromMemory(&backingStoreDimenstions, m_data.data.data(), 32); >- break; >- default: >- ASSERT_NOT_REACHED(); >- break; >- } >- } >-#if USE(IOSURFACE_CANVAS_BACKING_STORE) >- else >- image = m_data.surface->createImage(); >-#endif >- >- return image; >-} >- >-void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >-{ >- imageBuffer->draw(destContext, destRect, srcRect, options); >-} >- >-void ImageBuffer::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >-{ >- FloatRect adjustedSrcRect = srcRect; >- adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale); >- >- auto compatibleBitmap = m_data.compatibleBitmap(destContext.platformContext()->renderTarget()); >- >- FloatSize currentImageSize = nativeImageSize(compatibleBitmap); >- if (currentImageSize.isZero()) >- return; >- >- destContext.drawNativeImage(compatibleBitmap, currentImageSize, destRect, adjustedSrcRect, options); >-} >- >-void ImageBuffer::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options) >-{ >- FloatRect adjustedSrcRect = srcRect; >- adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale); >- >- if (!context().isAcceleratedContext()) { >- if (&destContext == &context() || destContext.isAcceleratedContext()) { >- if (RefPtr<Image> copy = copyImage(CopyBackingStore)) // Drawing into our own buffer, need to deep copy. >- copy->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >- } else { >- if (RefPtr<Image> imageForRendering = copyImage(DontCopyBackingStore)) >- imageForRendering->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >- } >- } else { >- if (RefPtr<Image> copy = copyImage(CopyBackingStore)) >- copy->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >- } >-} >- >-RefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- >- IntRect srcRect = rect; >- if (coordinateSystem == LogicalCoordinateSystem) >- srcRect.scale(m_resolutionScale); >- >- if (pixelArrayDimensions) >- *pixelArrayDimensions = srcRect.size(); >- >- return m_data.getData(AlphaPremultiplication::Unpremultiplied, srcRect, internalSize(), context().isAcceleratedContext(), 1); >-} >- >-RefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, IntSize* pixelArrayDimensions, CoordinateSystem coordinateSystem) const >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- >- IntRect srcRect = rect; >- if (coordinateSystem == LogicalCoordinateSystem) >- srcRect.scale(m_resolutionScale); >- >- if (pixelArrayDimensions) >- *pixelArrayDimensions = srcRect.size(); >- >- return m_data.getData(AlphaPremultiplication::Premultiplied, srcRect, internalSize(), context().isAcceleratedContext(), 1); >-} >- >-void ImageBuffer::putByteArray(const Uint8ClampedArray& source, AlphaPremultiplication bufferFormat, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem) >-{ >- if (context().isAcceleratedContext()) >- flushContext(); >- >- IntRect scaledSourceRect = sourceRect; >- IntSize scaledSourceSize = sourceSize; >- if (coordinateSystem == LogicalCoordinateSystem) { >- scaledSourceRect.scale(m_resolutionScale); >- scaledSourceSize.scale(m_resolutionScale); >- } >- >- m_data.putData(source, bufferFormat, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), context().isAcceleratedContext(), 1); >-} >- >-String ImageBuffer::toDataURL(const String&, Optional<double>, PreserveResolution) const >-{ >- notImplemented(); >- return "data:,"_s; >-} >- >-Vector<uint8_t> ImageBuffer::toData(const String& mimeType, Optional<double> quality) const >-{ >- notImplemented(); >- return { }; >-} >- >-String ImageDataToDataURL(const ImageData& source, const String& mimeType, const double* quality) >-{ >- notImplemented(); >- return "data:,"_s; >-} >- >-void ImageBuffer::transformColorSpace(ColorSpace, ColorSpace) >-{ >- notImplemented(); >-} >- >-} // namespace WebCore >- >-#endif >diff --git a/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp b/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..270abedf0a6350fd55948d481ab7895f620b48c3 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.cpp >@@ -0,0 +1,324 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "ImageBufferDirect2DBackend.h" >+ >+#if USE(DIRECT2D) >+ >+#include "BitmapImage.h" >+#include "COMPtr.h" >+#include "Direct2DUtilities.h" >+#include "GraphicsContext.h" >+#include "ImageData.h" >+#include "ImageDecoderDirect2D.h" >+#include "IntRect.h" >+#include "MIMETypeRegistry.h" >+#include "NotImplemented.h" >+#include "PlatformContextDirect2D.h" >+#include <d2d1_1.h> >+#include <math.h> >+#include <wincodec.h> >+#include <wtf/Assertions.h> >+#include <wtf/IsoMallocInlines.h> >+ >+namespace WebCore { >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBufferDirect2DBackend); >+ >+std::unique_ptr<ImageBufferDirect2DBackend> ImageBufferDirect2DBackend::create(const FloatSize& size, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+{ >+ IntSize backendSize = calculateBackendSize(size, resolutionScale); >+ if (backendSize.isEmpty()) >+ return nullptr; >+ >+ auto* platformContext = targetContext ? targetContext->platformContext() : nullptr; >+ auto* renderTarget = platformContext ? platformContext->renderTarget() : nullptr; >+ >+ if (!renderTarget) >+ renderTarget = GraphicsContext::defaultRenderTarget(); >+ >+ auto bitmapContext = Direct2D::createBitmapRenderTargetOfSize(size, renderTarget, resolutionScale); >+ if (!bitmapContext) >+ return; >+ >+ NativeImagePtr bitmap; >+ HRESULT hr = bitmapContext->GetBitmap(&bitmap); >+ if (!SUCCEEDED(hr)) >+ return; >+ >+ auto platformContext = makeUnique<PlatformContextDirect2D>(bitmapContext.get(), [this]() { >+ m_data.loadDataToBitmapIfNeeded(); >+ }, [this]() { >+ m_data.markBufferOutOfSync(); >+ }); >+ >+ if (!platformContext) >+ return nullptr; >+ >+ auto context = makeUnique<GraphicsContext>(platformContext.get(), GraphicsContext::BitmapRenderingContextType::GPUMemory); >+ if (!context) >+ return nullptr; >+ >+ return std::unique_ptr<ImageBufferDirect2DBackend>(new ImageBufferDirect2DBackend(size, backendSize, resolutionScale, colorSpace, WTFMove(platformContext), WTFMove(context), WTFMove(bitmap))); >+} >+ >+std::unique_ptr<ImageBufferDirect2DBackend> ImageBufferDirect2DBackend::create(const FloatSize& size, const GraphicsContext& context) >+{ >+ return ImageBufferDirect2DBackend::create(size, 1, ColorSpace::SRGB, nullptr); >+} >+ >+ImageBufferDirect2DBackend::ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& backendSize, float resolutionScale, ColorSpace colorSpace, std::unique_ptr<PlatformContextDirect2D>&& platformContext, std::unique_ptr<GraphicsContext>&& context, NativeImagePtr&& bitmap) >+ : ImageBufferCGBackend(logicalSize, backendSize, resolutionScale, colorSpace) >+ , m_platformContext(WTFMove(platformContext)) >+ , m_context(WTFMove(context)) >+ , m_bitmap(WTFMove(bitmap)) >+{ >+} >+ >+GraphicsContext& ImageBufferDirect2DBackend::context() const >+{ >+ return *m_context; >+} >+ >+void ImageBufferDirect2DBackend::flushContext() >+{ >+ context().flush(); >+} >+ >+NativeImagePtr ImageBufferDirect2DBackend::copyNativeImage(BackingStoreCopy copyBehavior) const >+{ >+ COMPtr<ID2D1BitmapRenderTarget> bitmapTarget; >+ HRESULT hr = context().platformContext()->renderTarget()->QueryInterface(&bitmapTarget); >+ if (!SUCCEEDED(hr)) >+ return nullptr; >+ >+ COMPtr<ID2D1Bitmap> image; >+ hr = bitmapTarget->GetBitmap(&image); >+ ASSERT(SUCCEEDED(hr)); >+ >+ // FIXME: m_data.data is nullptr even when asking to copy backing store leading to test failures. >+ if (copyBehavior == CopyBackingStore && m_data.data.isEmpty()) >+ copyBehavior = DontCopyBackingStore; >+ >+ Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(m_data.backingStoreSize.height()) * m_data.bytesPerRow; >+ if (numBytes.hasOverflowed()) >+ return nullptr; >+ >+ if (copyBehavior == CopyBackingStore) { >+ D2D1_RECT_U backingStoreDimenstions = IntRect(IntPoint(), m_data.backingStoreSize); >+ image->CopyFromMemory(&backingStoreDimenstions, m_data.data.data(), 32); >+ >+ } >+ >+ return image; >+} >+ >+static NativeImagePtr createCroppedImageIfNecessary(ID2D1BitmapRenderTarget* bitmapTarget, ID2D1Bitmap* image, const IntSize& bounds) >+{ >+ FloatSize imageSize = image ? nativeImageSize(image) : FloatSize(); >+ >+ if (image && (static_cast<size_t>(imageSize.width()) != static_cast<size_t>(bounds.width()) || static_cast<size_t>(imageSize.height()) != static_cast<size_t>(bounds.height()))) { >+ COMPtr<ID2D1Bitmap> croppedBitmap = Direct2D::createBitmap(bitmapTarget, bounds); >+ if (croppedBitmap) { >+ auto sourceRect = D2D1::RectU(0, 0, bounds.width(), bounds.height()); >+ HRESULT hr = croppedBitmap->CopyFromBitmap(nullptr, image, &sourceRect); >+ if (SUCCEEDED(hr)) >+ return croppedBitmap; >+ } >+ } >+ >+ return image; >+} >+ >+static RefPtr<Image> createBitmapImageAfterScalingIfNeeded(ID2D1BitmapRenderTarget* bitmapTarget, COMPtr<ID2D1Bitmap>&& image, IntSize internalSize, float resolutionScale, PreserveResolution preserveResolution) >+{ >+ if (resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >+ image = createCroppedImageIfNecessary(bitmapTarget, image.get(), internalSize); >+ else { >+ // FIXME: Need to implement scaled version >+ notImplemented(); >+ } >+ >+ if (!image) >+ return nullptr; >+ >+ return BitmapImage::create(WTFMove(image)); >+} >+ >+RefPtr<Image> ImageBufferDirect2DBackend::copyImage(BackingStoreCopy copyBehavior, PreserveResolution preserveResolution) const >+{ >+ NativeImagePtr image; >+ if (m_resolutionScale == 1 || preserveResolution == PreserveResolution::Yes) >+ image = copyNativeImage(copyBehavior); >+ else >+ image = copyNativeImage(DontCopyBackingStore); >+ >+ auto bitmapTarget = reinterpret_cast<ID2D1BitmapRenderTarget*>(context().platformContext()); >+ return createBitmapImageAfterScalingIfNeeded(bitmapTarget, WTFMove(image), internalSize(), resolutionScale(), preserveResolution); >+} >+ >+RefPtr<Image> ImageBufferDirect2DBackend::sinkIntoImage(PreserveResolution preserveResolution) >+{ >+ COMPtr<ID2D1BitmapRenderTarget> bitmapTarget; >+ HRESULT hr = context().platformContext()->renderTarget()->QueryInterface(&bitmapTarget); >+ if (!SUCCEEDED(hr)) >+ return nullptr; >+ >+ NativeImagePtr image = copyNativeImage(DontCopyBackingStore); >+ return createBitmapImageAfterScalingIfNeeded(bitmapTarget.get(), WTFMove(image), internalSize(), resolutionScale(), preserveResolution); >+} >+ >+NativeImagePtr ImageBufferDirect2DBackend::compatibleBitmap(ID2D1RenderTarget* renderTarget) >+{ >+ loadDataToBitmapIfNeeded(); >+ >+ if (!renderTarget) >+ return bitmap; >+ >+ if (m_platformContext->renderTarget() == renderTarget) { >+ COMPtr<ID2D1BitmapRenderTarget> bitmapTarget(Query, renderTarget); >+ if (bitmapTarget) { >+ COMPtr<ID2D1Bitmap> backingBitmap; >+ if (SUCCEEDED(bitmapTarget->GetBitmap(&backingBitmap))) { >+ if (backingBitmap != m_bitmap) >+ return bitmap; >+ >+ // We can't draw an ID2D1Bitmap to itself. Must return a copy. >+ COMPtr<ID2D1Bitmap> copiedBitmap; >+ if (SUCCEEDED(renderTarget->CreateBitmap(bitmap->GetPixelSize(), Direct2D::bitmapProperties(), &copiedBitmap))) { >+ if (SUCCEEDED(copiedBitmap->CopyFromBitmap(nullptr, m_bitmap.get(), nullptr))) >+ return copiedBitmap; >+ } >+ } >+ } >+ } >+ >+ auto size = m_bitmap->GetPixelSize(); >+ ASSERT(size.height && size.width); >+ >+ Checked<unsigned, RecordOverflow> numBytes = size.width * size.height * 4; >+ if (numBytes.hasOverflowed()) >+ return nullptr; >+ >+ // Copy the bits from current renderTarget to the output target. >+ // We cannot access the data backing an IWICBitmap while an active draw session is open. >+ context->endDraw(); >+ >+ COMPtr<ID2D1DeviceContext> sourceDeviceContext = m_platformContext->deviceContext(); >+ if (!sourceDeviceContext) >+ return nullptr; >+ >+ COMPtr<ID2D1Bitmap1> sourceCPUBitmap; >+ D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, Direct2D::pixelFormat()); >+ HRESULT hr = sourceDeviceContext->CreateBitmap(m_bitmap->GetPixelSize(), nullptr, bytesPerRow.unsafeGet(), bitmapProperties, &sourceCPUBitmap); >+ if (!SUCCEEDED(hr)) >+ return nullptr; >+ >+ if (!sourceCPUBitmap) >+ return nullptr; >+ >+ hr = sourceCPUBitmap->CopyFromBitmap(nullptr, m_bitmap.get(), nullptr); >+ if (!SUCCEEDED(hr)) >+ return nullptr; >+ >+ D2D1_MAPPED_RECT mappedSourceData; >+ hr = sourceCPUBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedSourceData); >+ if (!SUCCEEDED(hr)) >+ return nullptr; >+ >+ COMPtr<ID2D1DeviceContext> targetDeviceContext; >+ hr = renderTarget->QueryInterface(&targetDeviceContext); >+ ASSERT(SUCCEEDED(hr)); >+ >+ COMPtr<ID2D1Bitmap> compatibleBitmap; >+ hr = targetDeviceContext->CreateBitmap(bitmap->GetPixelSize(), mappedSourceData.bits, mappedSourceData.pitch, Direct2D::bitmapProperties(), &compatibleBitmap); >+ if (!SUCCEEDED(hr)) >+ return nullptr; >+ >+ hr = sourceCPUBitmap->Unmap(); >+ ASSERT(SUCCEEDED(hr)); >+ >+ context->beginDraw(); >+ >+ return compatibleBitmap; >+} >+ >+void ImageBufferDirect2DBackend::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const ImagePaintingOptions& options) >+{ >+ FloatRect adjustedSrcRect = srcRect; >+ adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale); >+ >+ auto compatibleBitmap = compatibleBitmap(destContext.platformContext()->renderTarget()); >+ >+ FloatSize currentImageSize = nativeImageSize(compatibleBitmap); >+ if (currentImageSize.isZero()) >+ return; >+ >+ destContext.drawNativeImage(compatibleBitmap, currentImageSize, destRect, adjustedSrcRect, options); >+} >+ >+void ImageBufferDirect2DBackend::drawPattern(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, const ImagePaintingOptions& options) >+{ >+ FloatRect adjustedSrcRect = srcRect; >+ adjustedSrcRect.scale(m_resolutionScale); >+ >+ if (auto image = copyImage(&destContext == &context() ? CopyBackingStore : DontCopyBackingStore)) >+ image->drawPattern(destContext, destRect, adjustedSrcRect, patternTransform, phase, spacing, options); >+} >+ >+String ImageBufferDirect2DBackend::toDataURL(const String&, Optional<double>, PreserveResolution) const >+{ >+ notImplemented(); >+ return "data:,"_s; >+} >+ >+Vector<uint8_t> ImageBufferDirect2DBackend::toData(const String& mimeType, Optional<double> quality) const >+{ >+ notImplemented(); >+ return { }; >+} >+ >+Vector<uint8_t> ImageBufferDirect2DBackend::toBGRAData() const >+{ >+ notImplemented(); >+ return { }; >+} >+ >+RefPtr<ImageData> ImageBufferDirect2DBackend::getImageData(AlphaPremultiplication outputFormat, const IntRect& srcRect) const >+{ >+ notImplemented(); >+ return ImageBufferBackend::getImageData(outputFormat, srcRect, nullptr); >+} >+ >+void ImageBufferDirect2DBackend::putImageData(AlphaPremultiplication inputFormat, const ImageData& imageData, const IntRect& srcRect, const IntPoint& destPoint) >+{ >+ notImplemented(); >+ ImageBufferBackend::putImageData(inputFormat, imageData, srcRect, destPoint, nullptr); >+} >+ >+} // namespace WebCore >+ >+#endif // USE(DIRECT2D) >diff --git a/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h b/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3d15607f3643dba7ee5eeff2f71ac39396007e13 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/win/ImageBufferDirect2DBackend.h >@@ -0,0 +1,67 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(DIRECT2D) >+ >+#include "ImageBufferBackend.h" >+#include <wtf/IsoMalloc.h> >+ >+namespace WebCore { >+ >+class ImageBufferDirect2DBackend : public ImageBufferBackend { >+ WTF_MAKE_ISO_ALLOCATED(ImageBufferDirect2DBackend); >+ WTF_MAKE_NONCOPYABLE(ImageBufferDirect2DBackend); >+public: >+ static std::unique_ptr<ImageBufferDirect2DBackend> create(const FloatSize&, float resolutionScale, ColorSpace, const HostWindow*); >+ static std::unique_ptr<ImageBufferDirect2DBackend> create(const FloatSize&, const GraphicsContext&); >+ >+ GraphicsContext& context() const override; >+ void flushContext() override; >+ >+ NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const override; >+ RefPtr<Image> copyImage(BackingStoreCopy, PreserveResolution) const override; >+ >+ RefPtr<Image> sinkIntoImage(PreserveResolution) override; >+ >+ String toDataURL(const String& mimeType, Optional<double> quality, PreserveResolution) const override; >+ Vector<uint8_t> toData(const String& mimeType, Optional<double> quality) const override; >+ Vector<uint8_t> toBGRAData() const override; >+ >+ RefPtr<ImageData> getImageData(AlphaPremultiplication outputFormat, const IntRect&) const override; >+ void putImageData(AlphaPremultiplication inputFormat, const ImageData&, const IntRect& srcRect, const IntPoint& destPoint) override; >+ >+protected: >+ ImageBufferDirect2DBackend(const FloatSize& logicalSize, const IntSize& physicalSize, float resolutionScale, ColorSpace); >+ >+ std::unique_ptr<PlatformContextDirect2D> m_platformContext; >+ std::unique_ptr<GraphicsContext> m_context; >+ NativeImagePtr m_bitmap; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(DIRECT2D) >diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp >index 49367cb29d0f20d171220b3200c94e5ccd3701bd..32bf86bc6fb68c1e6d63ded876275353d54afb83 100644 >--- a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp >+++ b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp >@@ -58,7 +58,7 @@ public: > > int fpsNumerator, fpsDenominator; > gst_util_double_to_fraction(frameRate(), &fpsNumerator, &fpsDenominator); >- auto imageSize = imageBuffer->internalSize(); >+ auto imageSize = imageBuffer->backendSize(); > auto caps = adoptGRef(gst_caps_new_simple("video/x-raw", > "format", G_TYPE_STRING, "BGRA", > "width", G_TYPE_INT, imageSize.width(), >diff --git a/Source/WebCore/rendering/shapes/Shape.cpp b/Source/WebCore/rendering/shapes/Shape.cpp >index 851a866789b4835422c57a41dda75a0bcad7d675..042d5dd7bb834f1e3bea1a9e1a902fe3db6effb0 100644 >--- a/Source/WebCore/rendering/shapes/Shape.cpp >+++ b/Source/WebCore/rendering/shapes/Shape.cpp >@@ -35,6 +35,7 @@ > #include "BoxShape.h" > #include "GraphicsContext.h" > #include "ImageBuffer.h" >+#include "ImageData.h" > #include "LengthFunctions.h" > #include "PolygonShape.h" > #include "RasterShape.h" >@@ -188,8 +189,9 @@ std::unique_ptr<Shape> Shape::createRasterShape(Image* image, float threshold, c > if (image) > graphicsContext.drawImage(*image, IntRect(IntPoint(), imageRect.size())); > >- RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageRect.size())); >- RELEASE_ASSERT(pixelArray); >+ auto imageData = imageBuffer->getImageData(AlphaPremultiplication::Unpremultiplied, { IntPoint(), imageRect.size() }); >+ RELEASE_ASSERT(imageData && imageData->data()); >+ auto* pixelArray = imageData->data(); > unsigned pixelArrayLength = pixelArray->length(); > unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA. > uint8_t alphaPixelThreshold = static_cast<uint8_t>(lroundf(clampTo<float>(threshold, 0, 1) * 255.0f)); >diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp >index 6075f63e1c28007f677e2937c5ca7bc679332028..f6a954589858e00e4e7b6a3c19f22bafa5761d34 100644 >--- a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp >+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp >@@ -346,7 +346,7 @@ bool SVGRenderingContext::bufferForeground(std::unique_ptr<ImageBuffer>& imageBu > AffineTransform transform = m_paintInfo->context().getCTM(GraphicsContext::DefinitelyIncludeDeviceScale); > IntSize expandedBoundingBox = expandedIntSize(boundingBox.size()); > IntSize bufferSize(static_cast<int>(ceil(expandedBoundingBox.width() * transform.xScale())), static_cast<int>(ceil(expandedBoundingBox.height() * transform.yScale()))); >- if (bufferSize != imageBuffer->internalSize()) >+ if (bufferSize != imageBuffer->backendSize()) > imageBuffer.reset(); > } > >diff --git a/Source/WebKit/DerivedSources-input.xcfilelist b/Source/WebKit/DerivedSources-input.xcfilelist >index 51d318b724e7519d7277ae750773d1b28e8ddaa3..b01b54c170900973ebbeac16d388db1d0f8225f5 100644 >--- a/Source/WebKit/DerivedSources-input.xcfilelist >+++ b/Source/WebKit/DerivedSources-input.xcfilelist >@@ -15,6 +15,8 @@ $(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/models.py > $(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/xxd.pl > $(PROJECT_DIR)/GPUProcess/GPUConnectionToWebProcess.messages.in > $(PROJECT_DIR)/GPUProcess/GPUProcess.messages.in >+$(PROJECT_DIR)/GPUProcess/RenderingBackend/RemoteImageBufferProxy.messages.in >+$(PROJECT_DIR)/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.messages.in > $(PROJECT_DIR)/GPUProcess/mac/com.apple.WebKit.GPUProcess.sb.in > $(PROJECT_DIR)/GPUProcess/media/RemoteMediaPlayerManagerProxy.messages.in > $(PROJECT_DIR)/GPUProcess/media/RemoteMediaPlayerProxy.messages.in >@@ -107,6 +109,7 @@ $(PROJECT_DIR)/WebProcess/Cache/WebCacheStorageConnection.messages.in > $(PROJECT_DIR)/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.messages.in > $(PROJECT_DIR)/WebProcess/FullScreen/WebFullScreenManager.messages.in > $(PROJECT_DIR)/WebProcess/GPU/GPUProcessConnection.messages.in >+$(PROJECT_DIR)/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.messages.in > $(PROJECT_DIR)/WebProcess/GPU/media/MediaPlayerPrivateRemote.messages.in > $(PROJECT_DIR)/WebProcess/GPU/media/RemoteMediaPlayerManager.messages.in > $(PROJECT_DIR)/WebProcess/GPU/webrtc/LibWebRTCCodecs.messages.in >diff --git a/Source/WebKit/DerivedSources-output.xcfilelist b/Source/WebKit/DerivedSources-output.xcfilelist >index 5c92b813353df71fe6d6850f37c4f73fccf71e5e..0a777f7237108d114f6a48ed1ac4b7b2628c328b 100644 >--- a/Source/WebKit/DerivedSources-output.xcfilelist >+++ b/Source/WebKit/DerivedSources-output.xcfilelist >@@ -129,6 +129,12 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRenderer > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererMessageReceiver.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererMessages.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteAudioMediaStreamTrackRendererMessagesReplies.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteImageBufferMessageReceiver.cpp >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteImageBufferMessages.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteImageBufferMessagesReplies.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteImageBufferProxyMessageReceiver.cpp >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteImageBufferProxyMessages.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteImageBufferProxyMessagesReplies.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteLayerTreeDrawingAreaProxyMessageReceiver.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteLayerTreeDrawingAreaProxyMessages.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteLayerTreeDrawingAreaProxyMessagesReplies.h >@@ -154,6 +160,9 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteMediaResourceManagerMessagesR > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteObjectRegistryMessageReceiver.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteObjectRegistryMessages.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteObjectRegistryMessagesReplies.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteRenderingBackendProxyMessageReceiver.cpp >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteRenderingBackendProxyMessages.h >+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteRenderingBackendProxyMessagesReplies.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteSampleBufferDisplayLayerManagerMessageReceiver.cpp > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteSampleBufferDisplayLayerManagerMessages.h > $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/RemoteSampleBufferDisplayLayerManagerMessagesReplies.h >diff --git a/Source/WebKit/DerivedSources.make b/Source/WebKit/DerivedSources.make >index 349e54dc30c44982bcd82e09e94bb66de99dcb11..60be198e8dfccf9fa860992ac7b65f09c6a9f20b 100644 >--- a/Source/WebKit/DerivedSources.make >+++ b/Source/WebKit/DerivedSources.make >@@ -25,6 +25,7 @@ VPATH = \ > $(WebKit2)/GPUProcess \ > $(WebKit2)/GPUProcess/mac \ > $(WebKit2)/GPUProcess/media \ >+ $(WebKit2)/GPUProcess/RenderingBackend \ > $(WebKit2)/GPUProcess/webrtc \ > $(WebKit2)/NetworkProcess \ > $(WebKit2)/NetworkProcess/Cookies \ >@@ -52,6 +53,7 @@ VPATH = \ > $(WebKit2)/WebProcess/Geolocation \ > $(WebKit2)/WebProcess/GPU \ > $(WebKit2)/WebProcess/GPU/media \ >+ $(WebKit2)/WebProcess/GPU/RenderingBackend \ > $(WebKit2)/WebProcess/GPU/webrtc \ > $(WebKit2)/WebProcess/IconDatabase \ > $(WebKit2)/WebProcess/Inspector \ >@@ -145,6 +147,8 @@ MESSAGE_RECEIVERS = \ > PluginProxy \ > RemoteAudioMediaStreamTrackRendererManager \ > RemoteAudioMediaStreamTrackRenderer \ >+ RemoteImageBuffer \ >+ RemoteImageBufferProxy \ > RemoteLayerTreeDrawingAreaProxy \ > RemoteMediaPlayerManager \ > RemoteMediaPlayerManagerProxy \ >@@ -153,6 +157,7 @@ MESSAGE_RECEIVERS = \ > RemoteMediaRecorderManager \ > RemoteMediaResourceManager \ > RemoteObjectRegistry \ >+ RemoteRenderingBackendProxy \ > RemoteSampleBufferDisplayLayer \ > RemoteSampleBufferDisplayLayerManager \ > RemoteScrollingCoordinator \ >diff --git a/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp b/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp >index a6cee54c97c9215a6873f4dcb12bde47c1dc40ec..a6a54fe118d07d8d4492f1d6c93eceaed0371d70 100644 >--- a/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp >+++ b/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp >@@ -186,79 +186,92 @@ LibWebRTCCodecsProxy& GPUConnectionToWebProcess::libWebRTCCodecsProxy() > } > #endif > >-void GPUConnectionToWebProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) >+void GPUConnectionToWebProcess::createRenderingBackend(RenderingBackendIdentifier renderingBackendIdentifier) >+{ >+ ASSERT(!m_remoteRenderingBackendProxy); >+ m_remoteRenderingBackendProxy = RemoteRenderingBackendProxy::create(*this, renderingBackendIdentifier); >+} >+ >+void GPUConnectionToWebProcess::releaseRenderingBackend(RenderingBackendIdentifier renderingBackendIdentifier) >+{ >+ ASSERT(m_remoteRenderingBackendProxy); >+ ASSERT(m_remoteRenderingBackendProxy->renderingBackendIdentifier() == renderingBackendIdentifier); >+ m_remoteRenderingBackendProxy = nullptr; >+} >+ >+bool GPUConnectionToWebProcess::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder) > { > if (decoder.messageReceiverName() == Messages::RemoteMediaPlayerManagerProxy::messageReceiverName()) { > remoteMediaPlayerManagerProxy().didReceiveMessageFromWebProcess(connection, decoder); >- return; >+ return true; > } else if (decoder.messageReceiverName() == Messages::RemoteMediaPlayerProxy::messageReceiverName()) { > remoteMediaPlayerManagerProxy().didReceivePlayerMessage(connection, decoder); >- return; >+ return true; > } else if (decoder.messageReceiverName() == Messages::RemoteMediaResourceManager::messageReceiverName()) { > remoteMediaResourceManager().didReceiveMessage(connection, decoder); >- return; >+ return true; > } > #if ENABLE(MEDIA_STREAM) > if (decoder.messageReceiverName() == Messages::UserMediaCaptureManagerProxy::messageReceiverName()) { > userMediaCaptureManagerProxy().didReceiveMessageFromGPUProcess(connection, decoder); >- return; >+ return true; > } > if (decoder.messageReceiverName() == Messages::RemoteMediaRecorderManager::messageReceiverName()) { > mediaRecorderManager().didReceiveMessageFromWebProcess(connection, decoder); >- return; >+ return true; > } > if (decoder.messageReceiverName() == Messages::RemoteMediaRecorder::messageReceiverName()) { > mediaRecorderManager().didReceiveRemoteMediaRecorderMessage(connection, decoder); >- return; >+ return true; > } > #if PLATFORM(COCOA) && ENABLE(VIDEO_TRACK) > if (decoder.messageReceiverName() == Messages::RemoteAudioMediaStreamTrackRendererManager::messageReceiverName()) { > audioTrackRendererManager().didReceiveMessageFromWebProcess(connection, decoder); >- return; >+ return true; > } > if (decoder.messageReceiverName() == Messages::RemoteAudioMediaStreamTrackRenderer::messageReceiverName()) { > audioTrackRendererManager().didReceiveRendererMessage(connection, decoder); >- return; >+ return true; > } > if (decoder.messageReceiverName() == Messages::RemoteSampleBufferDisplayLayerManager::messageReceiverName()) { > sampleBufferDisplayLayerManager().didReceiveMessageFromWebProcess(connection, decoder); >- return; >+ return true; > } > if (decoder.messageReceiverName() == Messages::RemoteSampleBufferDisplayLayer::messageReceiverName()) { > sampleBufferDisplayLayerManager().didReceiveLayerMessage(connection, decoder); >- return; >+ return true; > } > #endif > #endif > #if PLATFORM(COCOA) && USE(LIBWEBRTC) > if (decoder.messageReceiverName() == Messages::LibWebRTCCodecsProxy::messageReceiverName()) { > libWebRTCCodecsProxy().didReceiveMessageFromWebProcess(connection, decoder); >- return; >+ return true; > } > #endif >+ return messageReceiverMap().dispatchMessage(connection, decoder); > } > >-void GPUConnectionToWebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) >+bool GPUConnectionToWebProcess::dispatchSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) > { > if (decoder.messageReceiverName() == Messages::RemoteMediaPlayerManagerProxy::messageReceiverName()) { > remoteMediaPlayerManagerProxy().didReceiveSyncMessageFromWebProcess(connection, decoder, replyEncoder); >- return; >+ return true; > } > > #if ENABLE(MEDIA_STREAM) > if (decoder.messageReceiverName() == Messages::UserMediaCaptureManagerProxy::messageReceiverName()) { > userMediaCaptureManagerProxy().didReceiveSyncMessageFromGPUProcess(connection, decoder, replyEncoder); >- return; >+ return true; > } > #if PLATFORM(COCOA) && ENABLE(VIDEO_TRACK) > if (decoder.messageReceiverName() == Messages::RemoteSampleBufferDisplayLayerManager::messageReceiverName()) { > sampleBufferDisplayLayerManager().didReceiveSyncMessageFromWebProcess(connection, decoder, replyEncoder); >- return; >+ return true; > } > #endif > #endif >- >- ASSERT_NOT_REACHED(); >+ return messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder); > } > > const String& GPUConnectionToWebProcess::mediaCacheDirectory() const >diff --git a/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h b/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h >index 2b9bd1f887badafa4ea5c4ba34169d8b978fd62d..40faebdf8e129612eb73cf58bad47cb2e932d840 100644 >--- a/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h >+++ b/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h >@@ -28,13 +28,15 @@ > #if ENABLE(GPU_PROCESS) > > #include "Connection.h" >-#include "GPUConnectionToWebProcessMessagesReplies.h" >-#include <WebCore/DisplayListItems.h> >+#include "GPUConnectionToWebProcessMessages.h" >+#include "MessageReceiverMap.h" >+#include "RemoteRenderingBackendProxy.h" >+#include "RenderingBackendIdentifier.h" > #include <WebCore/ProcessIdentifier.h> > #include <pal/SessionID.h> > #include <wtf/Logger.h> > #include <wtf/RefCounted.h> >-#include <wtf/UniqueRef.h> >+#include <wtf/WeakPtr.h> > > namespace WebKit { > >@@ -49,18 +51,20 @@ class UserMediaCaptureManagerProxy; > > class GPUConnectionToWebProcess > : public RefCounted<GPUConnectionToWebProcess> >+ , public CanMakeWeakPtr<GPUConnectionToWebProcess> > , IPC::Connection::Client { > public: > static Ref<GPUConnectionToWebProcess> create(GPUProcess&, WebCore::ProcessIdentifier, IPC::Connection::Identifier, PAL::SessionID); > virtual ~GPUConnectionToWebProcess(); > > IPC::Connection& connection() { return m_connection.get(); } >+ IPC::MessageReceiverMap& messageReceiverMap() { return m_messageReceiverMap; } > GPUProcess& gpuProcess() { return m_gpuProcess.get(); } >+ WebCore::ProcessIdentifier webProcessIdentifier() const { return m_webProcessIdentifier; } > > void cleanupForSuspension(Function<void()>&&); > void endSuspension(); > >- WebCore::ProcessIdentifier webProcessIdentifier() const { return m_webProcessIdentifier; } > RemoteMediaResourceManager& remoteMediaResourceManager(); > > Logger& logger(); >@@ -85,17 +89,23 @@ private: > RemoteSampleBufferDisplayLayerManager& sampleBufferDisplayLayerManager(); > #endif > #endif >- >+ void createRenderingBackend(RenderingBackendIdentifier); >+ void releaseRenderingBackend(RenderingBackendIdentifier); >+ > // IPC::Connection::Client > void didClose(IPC::Connection&) final; >- void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) final; > void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final; > void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) final; >+ void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) final; >+ >+ bool dispatchMessage(IPC::Connection&, IPC::Decoder&); >+ bool dispatchSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); > > RefPtr<Logger> m_logger; > > Ref<IPC::Connection> m_connection; > Ref<GPUProcess> m_gpuProcess; >+ IPC::MessageReceiverMap m_messageReceiverMap; > const WebCore::ProcessIdentifier m_webProcessIdentifier; > std::unique_ptr<RemoteMediaResourceManager> m_remoteMediaResourceManager; > std::unique_ptr<RemoteMediaPlayerManagerProxy> m_remoteMediaPlayerManagerProxy; >@@ -111,6 +121,7 @@ private: > #if PLATFORM(COCOA) && USE(LIBWEBRTC) > std::unique_ptr<LibWebRTCCodecsProxy> m_libWebRTCCodecsProxy; > #endif >+ std::unique_ptr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy; > }; > > } // namespace WebKit >diff --git a/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in b/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in >index 3d40a5712e02d149d14f92f56e445346c01221d8..932c0122de081ede9bb9efb56f9bc5259ba4d704 100644 >--- a/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in >+++ b/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in >@@ -22,7 +22,9 @@ > > #if ENABLE(GPU_PROCESS) > >-messages -> GPUConnectionToWebProcess { >+messages -> GPUConnectionToWebProcess WantsDispatchMessage { >+ void CreateRenderingBackend(WebKit::RenderingBackendIdentifier renderingBackendIdentifier) >+ void ReleaseRenderingBackend(WebKit::RenderingBackendIdentifier renderingBackendIdentifier) > } > > #endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.cpp b/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..fbcfc45f55b205bc0056e237d440301da91d6ab1 >--- /dev/null >+++ b/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.cpp >@@ -0,0 +1,67 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RemoteImageBufferProxy.h" >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "RemoteImageBufferMessages.h" >+#include "RemoteImageBufferProxyMessages.h" >+ >+namespace WebKit { >+using namespace WebCore; >+ >+RemoteImageBufferProxy::RemoteImageBufferProxy(GPUConnectionToWebProcess& gpuConnectionToWebProcess, ImageBufferIdentifier imageBufferIdentifier) >+ : m_gpuConnectionToWebProcess(makeWeakPtr(gpuConnectionToWebProcess)) >+ , m_imageBufferIdentifier(imageBufferIdentifier) >+{ >+ // Register itself as a MessageReceiver in the GPUConnectionToWebProcess. >+ if (auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get()) >+ gpuConnectionToWebProcess->messageReceiverMap().addMessageReceiver(Messages::RemoteImageBufferProxy::messageReceiverName(), m_imageBufferIdentifier.toUInt64(), *this); >+} >+ >+RemoteImageBufferProxy::~RemoteImageBufferProxy() >+{ >+ // Un-register itself as a MessageReceiver. >+ if (auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get()) >+ gpuConnectionToWebProcess->messageReceiverMap().removeMessageReceiver(Messages::RemoteImageBufferProxy::messageReceiverName(), m_imageBufferIdentifier.toUInt64()); >+} >+ >+IPC::Connection* RemoteImageBufferProxy::messageSenderConnection() const >+{ >+ if (auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get()) >+ return &gpuConnectionToWebProcess->connection(); >+ return nullptr; >+} >+ >+uint64_t RemoteImageBufferProxy::messageSenderDestinationID() const >+{ >+ return m_imageBufferIdentifier.toUInt64(); >+} >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.h b/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.h >new file mode 100644 >index 0000000000000000000000000000000000000000..98130777d68535fac7514901290233ba812714a4 >--- /dev/null >+++ b/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.h >@@ -0,0 +1,61 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "ImageBufferIdentifier.h" >+#include "MessageReceiver.h" >+#include "MessageSender.h" >+#include <WebCore/DisplayListItems.h> >+#include <wtf/WeakPtr.h> >+ >+namespace WebKit { >+ >+class GPUConnectionToWebProcess; >+ >+class RemoteImageBufferProxy >+ : private IPC::MessageSender >+ , private IPC::MessageReceiver { >+public: >+ RemoteImageBufferProxy(GPUConnectionToWebProcess&, ImageBufferIdentifier); >+ ~RemoteImageBufferProxy(); >+ >+protected: >+ // IPC::MessageSender. >+ IPC::Connection* messageSenderConnection() const override; >+ uint64_t messageSenderDestinationID() const override; >+ >+ // IPC::MessageReceiver >+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; >+ >+ WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess; >+ ImageBufferIdentifier m_imageBufferIdentifier; >+}; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS >diff --git a/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.messages.in b/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.messages.in >new file mode 100644 >index 0000000000000000000000000000000000000000..ded189c29a53f5fc48e930bd64c8ecb9ed1b564c >--- /dev/null >+++ b/Source/WebKit/GPUProcess/RenderingBackend/RemoteImageBufferProxy.messages.in >@@ -0,0 +1,29 @@ >+# Copyright (C) 2020 Apple Inc. All rights reserved. >+# >+# Redistribution and use in source and binary forms, with or without >+# modification, are permitted provided that the following conditions >+# are met: >+# 1. Redistributions of source code must retain the above copyright >+# notice, this list of conditions and the following disclaimer. >+# 2. Redistributions in binary form must reproduce the above copyright >+# notice, this list of conditions and the following disclaimer in the >+# documentation and/or other materials provided with the distribution. >+# >+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND >+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR >+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR >+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER >+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, >+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ >+#if ENABLE(GPU_PROCESS) >+ >+messages -> RemoteImageBufferProxy NotRefCounted { >+} >+ >+#endif // ENABLE(GPU_PROCESS) >+ >diff --git a/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.cpp b/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..cd625279fcd61cf142bd145b1e5bdecd44095e4b >--- /dev/null >+++ b/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.cpp >@@ -0,0 +1,106 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RemoteRenderingBackendProxy.h" >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "RemoteRenderingBackendProxyMessages.h" >+ >+namespace WebKit { >+using namespace WebCore; >+ >+std::unique_ptr<RemoteRenderingBackendProxy> RemoteRenderingBackendProxy::create(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RenderingBackendIdentifier renderingBackendIdentifier) >+{ >+ return std::unique_ptr<RemoteRenderingBackendProxy>(new RemoteRenderingBackendProxy(gpuConnectionToWebProcess, renderingBackendIdentifier)); >+} >+ >+RemoteRenderingBackendProxy::RemoteRenderingBackendProxy(GPUConnectionToWebProcess& gpuConnectionToWebProcess, RenderingBackendIdentifier renderingBackendIdentifier) >+ : m_gpuConnectionToWebProcess(makeWeakPtr(gpuConnectionToWebProcess)) >+ , m_renderingBackendIdentifier(renderingBackendIdentifier) >+{ >+ if (auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get()) >+ gpuConnectionToWebProcess->messageReceiverMap().addMessageReceiver(Messages::RemoteRenderingBackendProxy::messageReceiverName(), renderingBackendIdentifier.toUInt64(), *this); >+} >+ >+RemoteRenderingBackendProxy::~RemoteRenderingBackendProxy() >+{ >+ if (auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get()) >+ gpuConnectionToWebProcess->messageReceiverMap().removeMessageReceiver(Messages::RemoteRenderingBackendProxy::messageReceiverName(), m_renderingBackendIdentifier.toUInt64()); >+} >+ >+IPC::Connection* RemoteRenderingBackendProxy::messageSenderConnection() const >+{ >+ if (auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get()) >+ return &gpuConnectionToWebProcess->connection(); >+ return nullptr; >+} >+ >+uint64_t RemoteRenderingBackendProxy::messageSenderDestinationID() const >+{ >+ return m_renderingBackendIdentifier.toUInt64(); >+} >+ >+void RemoteRenderingBackendProxy::createImageBuffer(const FloatSize& logicalSize, RenderingMode renderingMode, float resolutionScale, ColorSpace colorSpace, ImageBufferIdentifier imageBufferIdentifier) >+{ >+ if (m_imageBufferMap.contains(imageBufferIdentifier)) { >+ ASSERT_NOT_REACHED(); >+ return; >+ } >+ >+ auto* gpuConnectionToWebProcess = m_gpuConnectionToWebProcess.get(); >+ if (!gpuConnectionToWebProcess) >+ return; >+ >+ std::unique_ptr<ImageBuffer> imageBuffer; >+ >+ switch (renderingMode) { >+ case RenderingMode::RemoteAccelerated: >+ case RenderingMode::Remote: >+ // FIXME: create the remote ImageBuffer proxy. >+ default: >+ ASSERT_NOT_REACHED(); >+ } >+ >+ if (!imageBuffer) >+ return; >+ >+ m_imageBufferMap.add(imageBufferIdentifier, WTFMove(imageBuffer)); >+} >+ >+void RemoteRenderingBackendProxy::releaseImageBuffer(ImageBufferIdentifier imageBufferIdentifier) >+{ >+ // CreateImageBuffer message should have been received before this one. >+ if (!m_imageBufferMap.contains(imageBufferIdentifier)) { >+ ASSERT_NOT_REACHED(); >+ return; >+ } >+ m_imageBufferMap.remove(imageBufferIdentifier); >+} >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.h b/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f9527b875aa1325569ac226300fa6ad598e9ae0e >--- /dev/null >+++ b/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.h >@@ -0,0 +1,73 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "Connection.h" >+#include "ImageBufferIdentifier.h" >+#include "MessageReceiver.h" >+#include "MessageSender.h" >+#include "RenderingBackendIdentifier.h" >+#include <WebCore/ColorSpace.h> >+#include <WebCore/ImageBuffer.h> >+#include <wtf/WeakPtr.h> >+ >+namespace WebKit { >+ >+class GPUConnectionToWebProcess; >+ >+class RemoteRenderingBackendProxy >+ : private IPC::MessageSender >+ , private IPC::MessageReceiver { >+public: >+ static std::unique_ptr<RemoteRenderingBackendProxy> create(GPUConnectionToWebProcess&, RenderingBackendIdentifier); >+ virtual ~RemoteRenderingBackendProxy(); >+ >+ RenderingBackendIdentifier renderingBackendIdentifier() const { return m_renderingBackendIdentifier; } >+ >+private: >+ RemoteRenderingBackendProxy(GPUConnectionToWebProcess&, RenderingBackendIdentifier); >+ >+ // IPC::MessageSender. >+ IPC::Connection* messageSenderConnection() const override; >+ uint64_t messageSenderDestinationID() const override; >+ >+ // IPC::MessageReceiver >+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; >+ >+ void createImageBuffer(const WebCore::FloatSize& logicalSize, WebCore::RenderingMode, float resolutionScale, WebCore::ColorSpace, ImageBufferIdentifier); >+ void releaseImageBuffer(ImageBufferIdentifier); >+ >+ using ImageBufferMap = HashMap<ImageBufferIdentifier, std::unique_ptr<WebCore::ImageBuffer>>; >+ ImageBufferMap m_imageBufferMap; >+ WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess; >+ RenderingBackendIdentifier m_renderingBackendIdentifier; >+}; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.messages.in b/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.messages.in >new file mode 100644 >index 0000000000000000000000000000000000000000..e4dcf7f32b4526ddfbebb787f802c36fd957bc49 >--- /dev/null >+++ b/Source/WebKit/GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.messages.in >@@ -0,0 +1,30 @@ >+# Copyright (C) 2020 Apple Inc. All rights reserved. >+# >+# Redistribution and use in source and binary forms, with or without >+# modification, are permitted provided that the following conditions >+# are met: >+# 1. Redistributions of source code must retain the above copyright >+# notice, this list of conditions and the following disclaimer. >+# 2. Redistributions in binary form must reproduce the above copyright >+# notice, this list of conditions and the following disclaimer in the >+# documentation and/or other materials provided with the distribution. >+# >+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND >+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR >+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR >+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER >+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, >+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ >+#if ENABLE(GPU_PROCESS) >+ >+messages -> RemoteRenderingBackendProxy NotRefCounted { >+ void CreateImageBuffer(WebCore::FloatSize logicalSize, WebCore::RenderingMode renderingMode, float resolutionScale, WebCore::ColorSpace colorSpace, WebKit::ImageBufferIdentifier imageBufferIdentifier) >+ void ReleaseImageBuffer(WebKit::ImageBufferIdentifier imageBufferIdentifier) >+} >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayer.h b/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayer.h >index 685a669787176b13719cbb8fe993cdc1bce79ce8..6e6a217a5a205ee3708f340bad7463916c2d6e84 100644 >--- a/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayer.h >+++ b/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayer.h >@@ -32,6 +32,7 @@ > #include "MessageSender.h" > #include "SampleBufferDisplayLayerIdentifier.h" > #include <WebCore/SampleBufferDisplayLayer.h> >+#include <wtf/MediaTime.h> > > namespace WebCore { > class ImageTransferSessionVT; >diff --git a/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp b/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp >index 4b9be49cac72f44e717977c4a466e2e279f1b14e..fb0d2652e7dc715f3cbe90b01a74173128cdb57a 100644 >--- a/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp >+++ b/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp >@@ -32,6 +32,7 @@ > #include "RemoteSampleBufferDisplayLayer.h" > > namespace WebKit { >+using namespace WebCore; > > RemoteSampleBufferDisplayLayerManager::RemoteSampleBufferDisplayLayerManager(Ref<IPC::Connection>&& connection) > : m_connection(WTFMove(connection)) >diff --git a/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h b/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h >index 9f9b30c761623dd948d29be0f37f0ad0f47e5a9a..e38c5d6c05d0dfaf42681995b9e04f4e7647f0b5 100644 >--- a/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h >+++ b/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h >@@ -30,6 +30,7 @@ > #include "MessageReceiver.h" > #include "RemoteSampleBufferDisplayLayerManagerMessagesReplies.h" > #include "SampleBufferDisplayLayerIdentifier.h" >+#include <WebCore/IntSize.h> > #include <wtf/HashMap.h> > > namespace IPC { >diff --git a/Source/WebKit/Scripts/webkit/messages.py b/Source/WebKit/Scripts/webkit/messages.py >index 7c5ac0acf745b7a703cbec06bf7b1ac62ea842b0..183b5d5601ed02c424f718314c7c42698f111b08 100644 >--- a/Source/WebKit/Scripts/webkit/messages.py >+++ b/Source/WebKit/Scripts/webkit/messages.py >@@ -27,6 +27,7 @@ import sys > from webkit import parser > > WANTS_CONNECTION_ATTRIBUTE = 'WantsConnection' >+WANTS_DISPATCH_MESSAGE_ATTRIBUTE = 'WantsDispatchMessage' > LEGACY_RECEIVER_ATTRIBUTE = 'LegacyReceiver' > NOT_REFCOUNTED_RECEIVER_ATTRIBUTE = 'NotRefCounted' > SYNCHRONOUS_ATTRIBUTE = 'Synchronous' >@@ -204,6 +205,8 @@ def types_that_cannot_be_forward_declared(): > return frozenset([ > 'MachSendRight', > 'String', >+ 'WebCore::AlphaPremultiplication', >+ 'WebCore::ColorSpace', > 'WebCore::DocumentIdentifier', > 'WebCore::FetchIdentifier', > 'WebCore::FrameIdentifier', >@@ -212,6 +215,7 @@ def types_that_cannot_be_forward_declared(): > 'WebCore::PointerID', > 'WebCore::ProcessIdentifier', > 'WebCore::RealtimeMediaSourceIdentifier', >+ 'WebCore::RenderingMode', > 'WebCore::ServiceWorkerIdentifier', > 'WebCore::ServiceWorkerJobIdentifier', > 'WebCore::ServiceWorkerOrClientData', >@@ -221,12 +225,14 @@ def types_that_cannot_be_forward_declared(): > 'WebKit::ActivityStateChangeID', > 'WebKit::AudioMediaStreamTrackRendererIdentifier', > 'WebKit::ContentWorldIdentifier', >+ 'WebKit::ImageBufferIdentifier', > 'WebKit::LayerHostingContextID', > 'WebKit::MediaPlayerPrivateRemoteIdentifier', > 'WebKit::MediaRecorderIdentifier', > 'WebKit::RemoteMediaResourceIdentifier', > 'WebKit::RTCDecoderIdentifier', > 'WebKit::RTCEncoderIdentifier', >+ 'WebKit::RenderingBackendIdentifier', > 'WebKit::SampleBufferDisplayLayerIdentifier', > 'WebKit::StorageAreaIdentifier', > 'WebKit::StorageAreaImplIdentifier', >@@ -769,13 +775,16 @@ def generate_message_handler(receiver): > else: > async_messages.append(message) > >- if async_messages: >+ if async_messages or receiver.has_attribute(WANTS_DISPATCH_MESSAGE_ATTRIBUTE): > result.append('void %s::didReceive%sMessage(IPC::Connection& connection, IPC::Decoder& decoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else '')) > result.append('{\n') > if not receiver.has_attribute(NOT_REFCOUNTED_RECEIVER_ATTRIBUTE): > result.append(' auto protectedThis = makeRef(*this);\n') > > result += [async_message_statement(receiver, message) for message in async_messages] >+ if receiver.has_attribute(WANTS_DISPATCH_MESSAGE_ATTRIBUTE): >+ result.append(' if (dispatchMessage(connection, decoder))\n') >+ result.append(' return;\n') > if (receiver.superclass): > result.append(' %s::didReceiveMessage(connection, decoder);\n' % (receiver.superclass)) > else: >@@ -784,13 +793,16 @@ def generate_message_handler(receiver): > result.append(' ASSERT_NOT_REACHED();\n') > result.append('}\n') > >- if sync_messages: >+ if sync_messages or receiver.has_attribute(WANTS_DISPATCH_MESSAGE_ATTRIBUTE): > result.append('\n') > result.append('void %s::didReceiveSync%sMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else '')) > result.append('{\n') > if not receiver.has_attribute(NOT_REFCOUNTED_RECEIVER_ATTRIBUTE): > result.append(' auto protectedThis = makeRef(*this);\n') > result += [sync_message_statement(receiver, message) for message in sync_messages] >+ if receiver.has_attribute(WANTS_DISPATCH_MESSAGE_ATTRIBUTE): >+ result.append(' if (dispatchSyncMessage(connection, decoder, replyEncoder))\n') >+ result.append(' return;\n') > result.append(' UNUSED_PARAM(connection);\n') > result.append(' UNUSED_PARAM(decoder);\n') > result.append(' UNUSED_PARAM(replyEncoder);\n') >diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.h b/Source/WebKit/Shared/WebCoreArgumentCoders.h >index 7bf71c17abdd3d8b13190220058c9f9c219f60b3..d993c273a33dfab99f464a0b27c2ccfe590210a1 100644 >--- a/Source/WebKit/Shared/WebCoreArgumentCoders.h >+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.h >@@ -26,6 +26,7 @@ > #pragma once > > #include "ArgumentCoders.h" >+#include <WebCore/AlphaPremultiplication.h> > #include <WebCore/AutoplayEvent.h> > #include <WebCore/ColorSpace.h> > #include <WebCore/DiagnosticLoggingClient.h> >@@ -36,6 +37,7 @@ > #include <WebCore/NetworkLoadMetrics.h> > #include <WebCore/NotificationDirection.h> > #include <WebCore/RealtimeMediaSource.h> >+#include <WebCore/RenderingMode.h> > #include <WebCore/ScrollSnapOffsetsInfo.h> > #include <WebCore/ServiceWorkerTypes.h> > #include <WebCore/StoredCredentialsPolicy.h> >@@ -823,6 +825,14 @@ template<> struct ArgumentCoder<WebCore::SerializedAttachmentData> { > > namespace WTF { > >+template<> struct EnumTraits<WebCore::AlphaPremultiplication> { >+ using values = EnumValues< >+ WebCore::AlphaPremultiplication, >+ WebCore::AlphaPremultiplication::Premultiplied, >+ WebCore::AlphaPremultiplication::Unpremultiplied >+ >; >+}; >+ > template<> struct EnumTraits<WebCore::ColorSpace> { > using values = EnumValues< > WebCore::ColorSpace, >@@ -832,6 +842,18 @@ template<> struct EnumTraits<WebCore::ColorSpace> { > >; > }; > >+template<> struct EnumTraits<WebCore::RenderingMode> { >+ using values = EnumValues< >+ WebCore::RenderingMode, >+ WebCore::RenderingMode::Accelerated, >+ WebCore::RenderingMode::Unaccelerated, >+ WebCore::RenderingMode::DisplayListAccelerated, >+ WebCore::RenderingMode::DisplayList, >+ WebCore::RenderingMode::RemoteAccelerated, >+ WebCore::RenderingMode::Remote >+ >; >+}; >+ > template<> struct EnumTraits<WebCore::AutoplayEvent> { > using values = EnumValues< > WebCore::AutoplayEvent, >diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt >index 53109203ca22cb5f5db9351f9c236e053ab1e009..55aede6a9915068dfc8f5477f81be8cb8eac412e 100644 >--- a/Source/WebKit/Sources.txt >+++ b/Source/WebKit/Sources.txt >@@ -37,6 +37,8 @@ GPUProcess/media/RemoteMediaResource.cpp > GPUProcess/media/RemoteMediaResourceLoader.cpp > GPUProcess/media/RemoteMediaResourceManager.cpp > GPUProcess/media/RemoteVideoTrackProxy.cpp >+GPUProcess/RenderingBackend/RemoteImageBufferProxy.cpp >+GPUProcess/RenderingBackend/RemoteRenderingBackendProxy.cpp > > NetworkProcess/AdClickAttributionManager.cpp > NetworkProcess/NetworkActivityTracker.cpp >@@ -537,6 +539,8 @@ WebProcess/GPU/media/RemoteMediaPlayerManager.cpp > WebProcess/GPU/media/RemoteMediaPlayerMIMETypeCache.cpp @no-unify > WebProcess/GPU/media/RemoteMediaResourceProxy.cpp > WebProcess/GPU/media/VideoTrackPrivateRemote.cpp >+WebProcess/GPU/RenderingBackend/RemoteImageBuffer.cpp >+WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.cpp > WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp > WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp > WebProcess/GPU/webrtc/MediaRecorderProvider.cpp >diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt >index eaa0d84fa5cfa740d27b78b907ec9569931cb0dc..067019cfb78bdeb576f0583600c6724d854ce1c4 100644 >--- a/Source/WebKit/SourcesCocoa.txt >+++ b/Source/WebKit/SourcesCocoa.txt >@@ -638,14 +638,18 @@ WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm > // Derived Sources > EditableImageControllerMessageReceiver.cpp > GPUConnectionToWebProcessMessageReceiver.cpp >+GPUProcessConnectionMessageReceiver.cpp > GPUProcessProxyMessageReceiver.cpp > GPUProcessMessageReceiver.cpp > LibWebRTCCodecsProxyMessageReceiver.cpp > LibWebRTCCodecsMessageReceiver.cpp > RemoteAudioMediaStreamTrackRendererManagerMessageReceiver.cpp > RemoteAudioMediaStreamTrackRendererMessageReceiver.cpp >+RemoteImageBufferMessageReceiver.cpp >+RemoteImageBufferProxyMessageReceiver.cpp > RemoteMediaRecorderMessageReceiver.cpp > RemoteMediaRecorderManagerMessageReceiver.cpp >+RemoteRenderingBackendProxyMessageReceiver.cpp > RemoteSampleBufferDisplayLayerManagerMessageReceiver.cpp > RemoteSampleBufferDisplayLayerMessageReceiver.cpp > SampleBufferDisplayLayerMessageReceiver.cpp >diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >index be642204775e2555ccba5fde9f8e4ae8355eddd5..6c0a20064e0b2abaaa76105575dd7a29f62c32fe 100644 >--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj >+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >@@ -4038,6 +4038,19 @@ > 71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKTouchActionGestureRecognizer.h; path = ios/WKTouchActionGestureRecognizer.h; sourceTree = "<group>"; }; > 71A676A522C62318007D6295 /* WKTouchActionGestureRecognizer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKTouchActionGestureRecognizer.mm; path = ios/WKTouchActionGestureRecognizer.mm; sourceTree = "<group>"; }; > 71FB810A2260627A00323677 /* WebsiteSimulatedMouseEventsDispatchPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebsiteSimulatedMouseEventsDispatchPolicy.h; sourceTree = "<group>"; }; >+ 72506D3923E9F88B001E6E0D /* RemoteImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteImageBuffer.h; sourceTree = "<group>"; }; >+ 72506D3A23E9F88C001E6E0D /* RemoteImageBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteImageBuffer.cpp; sourceTree = "<group>"; }; >+ 72506D3B23E9F88C001E6E0D /* RemoteImageBuffer.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RemoteImageBuffer.messages.in; sourceTree = "<group>"; }; >+ 72506D3C23E9F8B9001E6E0D /* RemoteImageBufferProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteImageBufferProxy.h; sourceTree = "<group>"; }; >+ 72506D3D23E9F8B9001E6E0D /* RemoteImageBufferProxy.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RemoteImageBufferProxy.messages.in; sourceTree = "<group>"; }; >+ 72506D3E23E9F8B9001E6E0D /* RemoteImageBufferProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteImageBufferProxy.cpp; sourceTree = "<group>"; }; >+ 7256459E23E8FF0700A0632D /* RemoteRenderingBackendProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteRenderingBackendProxy.cpp; sourceTree = "<group>"; }; >+ 7256459F23E8FF0700A0632D /* RemoteRenderingBackendProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteRenderingBackendProxy.h; sourceTree = "<group>"; }; >+ 725645A023E8FF0700A0632D /* RemoteRenderingBackendProxy.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RemoteRenderingBackendProxy.messages.in; sourceTree = "<group>"; }; >+ 725645A123E8FF1500A0632D /* RenderingBackendIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderingBackendIdentifier.h; sourceTree = "<group>"; }; >+ 725645A223E8FF1500A0632D /* RemoteRenderingBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteRenderingBackend.h; sourceTree = "<group>"; }; >+ 725645A323E8FF1500A0632D /* RemoteRenderingBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteRenderingBackend.cpp; sourceTree = "<group>"; }; >+ 725645A423E907D100A0632D /* ImageBufferIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBufferIdentifier.h; sourceTree = "<group>"; }; > 728E86EF1795188C0087879E /* WebColorPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebColorPickerMac.h; sourceTree = "<group>"; }; > 728E86F01795188C0087879E /* WebColorPickerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebColorPickerMac.mm; sourceTree = "<group>"; }; > 75A8D2C4187CCF9F00C39C9E /* WKWebsiteDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebsiteDataStore.h; sourceTree = "<group>"; }; >@@ -6482,6 +6495,7 @@ > isa = PBXGroup; > children = ( > 0792312F239B3B0C009598E2 /* media */, >+ 7256459C23E8FE5C00A0632D /* RenderingBackend */, > 4172198823B6126100AE5686 /* webrtc */, > 2D7E43C023752CD900EA5CA0 /* GPUProcessConnection.cpp */, > 2D7E43C323752CD900EA5CA0 /* GPUProcessConnection.h */, >@@ -6498,6 +6512,7 @@ > 2D9FB2042375209D0049F936 /* ios */, > 2D9FB2062375209D0049F936 /* mac */, > 07C75C172399A3DB0088E65B /* media */, >+ 7256459D23E8FE8700A0632D /* RenderingBackend */, > 4172198E23B633CA00AE5686 /* webrtc */, > 2D9FB20C2375209D0049F936 /* GPUConnectionToWebProcess.cpp */, > 2D9FB2002375209D0049F936 /* GPUConnectionToWebProcess.h */, >@@ -7899,6 +7914,33 @@ > name = mac; > sourceTree = "<group>"; > }; >+ 7256459C23E8FE5C00A0632D /* RenderingBackend */ = { >+ isa = PBXGroup; >+ children = ( >+ 725645A423E907D100A0632D /* ImageBufferIdentifier.h */, >+ 72506D3A23E9F88C001E6E0D /* RemoteImageBuffer.cpp */, >+ 72506D3923E9F88B001E6E0D /* RemoteImageBuffer.h */, >+ 72506D3B23E9F88C001E6E0D /* RemoteImageBuffer.messages.in */, >+ 725645A323E8FF1500A0632D /* RemoteRenderingBackend.cpp */, >+ 725645A223E8FF1500A0632D /* RemoteRenderingBackend.h */, >+ 725645A123E8FF1500A0632D /* RenderingBackendIdentifier.h */, >+ ); >+ path = RenderingBackend; >+ sourceTree = "<group>"; >+ }; >+ 7256459D23E8FE8700A0632D /* RenderingBackend */ = { >+ isa = PBXGroup; >+ children = ( >+ 72506D3E23E9F8B9001E6E0D /* RemoteImageBufferProxy.cpp */, >+ 72506D3C23E9F8B9001E6E0D /* RemoteImageBufferProxy.h */, >+ 72506D3D23E9F8B9001E6E0D /* RemoteImageBufferProxy.messages.in */, >+ 7256459E23E8FF0700A0632D /* RemoteRenderingBackendProxy.cpp */, >+ 7256459F23E8FF0700A0632D /* RemoteRenderingBackendProxy.h */, >+ 725645A023E8FF0700A0632D /* RemoteRenderingBackendProxy.messages.in */, >+ ); >+ path = RenderingBackend; >+ sourceTree = "<group>"; >+ }; > 7A843A1D21E41FD900DEF663 /* Classifier */ = { > isa = PBXGroup; > children = ( >diff --git a/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp b/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp >index 8dff50f3088ed45c590ec81e2c09a138ba7a535f..0f9c7acef4e0ed873c4be089618a6df0417870f4 100644 >--- a/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp >+++ b/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp >@@ -62,10 +62,6 @@ void GPUProcessConnection::didClose(IPC::Connection&) > { > } > >-void GPUProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) >-{ >-} >- > #if PLATFORM(COCOA) && ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM) > SampleBufferDisplayLayerManager& GPUProcessConnection::sampleBufferDisplayLayerManager() > { >@@ -75,34 +71,44 @@ SampleBufferDisplayLayerManager& GPUProcessConnection::sampleBufferDisplayLayerM > } > #endif > >-void GPUProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) >+bool GPUProcessConnection::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder) > { > if (decoder.messageReceiverName() == Messages::MediaPlayerPrivateRemote::messageReceiverName()) { > WebProcess::singleton().supplement<RemoteMediaPlayerManager>()->didReceivePlayerMessage(connection, decoder); >- return; >+ return true; > } >- > #if ENABLE(MEDIA_STREAM) > if (decoder.messageReceiverName() == Messages::UserMediaCaptureManager::messageReceiverName()) { > if (auto* captureManager = WebProcess::singleton().supplement<UserMediaCaptureManager>()) > captureManager->didReceiveMessageFromGPUProcess(connection, decoder); >- return; >+ return true; > } > #if PLATFORM(COCOA) && ENABLE(VIDEO_TRACK) > if (decoder.messageReceiverName() == Messages::SampleBufferDisplayLayer::messageReceiverName()) { > sampleBufferDisplayLayerManager().didReceiveLayerMessage(connection, decoder); >- return; >+ return true; > } > #endif // PLATFORM(COCOA) && ENABLE(VIDEO_TRACK) > #endif // ENABLE(MEDIA_STREAM) > #if USE(LIBWEBRTC) && PLATFORM(COCOA) > if (decoder.messageReceiverName() == Messages::LibWebRTCCodecs::messageReceiverName()) { > WebProcess::singleton().libWebRTCCodecs().didReceiveMessage(connection, decoder); >- return; >+ return true; > } > #endif >+ return messageReceiverMap().dispatchMessage(connection, decoder); > } > >+bool GPUProcessConnection::dispatchSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) >+{ >+ return messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder); >+} >+ >+void GPUProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) >+{ >+} >+ >+ > } // namespace WebKit > > #endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h b/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h >index 4600e53bb284d748cf3911b94db5599a9cb45f27..7b6f88222c33736b8c427db4cbde1c0454886c82 100644 >--- a/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h >+++ b/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h >@@ -28,6 +28,7 @@ > #if ENABLE(GPU_PROCESS) > > #include "Connection.h" >+#include "MessageReceiverMap.h" > #include "SampleBufferDisplayLayerManager.h" > #include <wtf/RefCounted.h> > #include <wtf/text/WTFString.h> >@@ -47,6 +48,7 @@ public: > ~GPUProcessConnection(); > > IPC::Connection& connection() { return m_connection.get(); } >+ IPC::MessageReceiverMap& messageReceiverMap() { return m_messageReceiverMap; } > > #if HAVE(AUDIT_TOKEN) > void setAuditToken(Optional<audit_token_t> auditToken) { m_auditToken = auditToken; } >@@ -62,10 +64,15 @@ private: > // IPC::Connection::Client > void didClose(IPC::Connection&) override; > void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final; >+ void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) final; > void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; >+ >+ bool dispatchMessage(IPC::Connection&, IPC::Decoder&); >+ bool dispatchSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); > > // The connection from the web process to the GPU process. > Ref<IPC::Connection> m_connection; >+ IPC::MessageReceiverMap m_messageReceiverMap; > > #if HAVE(AUDIT_TOKEN) > Optional<audit_token_t> m_auditToken; >diff --git a/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in b/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in >index d36f8a095f6a77bbb6cac883a651e84ce9d64b30..57fecde9df27c739a6cbf0269806592b5e2179a7 100644 >--- a/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in >+++ b/Source/WebKit/WebProcess/GPU/GPUProcessConnection.messages.in >@@ -22,7 +22,7 @@ > > #if ENABLE(GPU_PROCESS) > >-messages -> GPUProcessConnection { >+messages -> GPUProcessConnection WantsDispatchMessage { > > } > >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/ImageBufferIdentifier.h b/Source/WebKit/WebProcess/GPU/RenderingBackend/ImageBufferIdentifier.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9a1bc9ae87dc8d72428a0b809cad0d80a4cd1cb9 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/ImageBufferIdentifier.h >@@ -0,0 +1,39 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include <wtf/ObjectIdentifier.h> >+ >+namespace WebKit { >+ >+enum ImageBufferIdentifierType { }; >+using ImageBufferIdentifier = ObjectIdentifier<ImageBufferIdentifierType>; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.cpp b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..614c2a1c2ff7dfeeb616bc867e3d8baea46d4e87 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.cpp >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RemoteImageBuffer.h" >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "GPUConnectionToWebProcessMessages.h" >+#include "GPUProcessConnection.h" >+#include "RemoteImageBufferMessages.h" >+#include "RemoteImageBufferProxyMessages.h" >+#include "RemoteRenderingBackendProxyMessages.h" >+ >+namespace WebKit { >+ >+using namespace WebCore; >+ >+RemoteImageBuffer::RemoteImageBuffer(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, ColorSpace colorSpace, RenderingBackendIdentifier renderingBackendIdentifier) >+ : m_renderingBackendIdentifier(renderingBackendIdentifier) >+{ >+ // Register itself as a MessageReceiver in the GPUProcessConnection. >+ IPC::MessageReceiverMap& messageReceiverMap = WebProcess::singleton().ensureGPUProcessConnection().messageReceiverMap(); >+ messageReceiverMap.addMessageReceiver(Messages::RemoteImageBuffer::messageReceiverName(), m_imageBufferIdentifier.toUInt64(), *this); >+ >+ // Create the RemoteImageBufferProxy. >+ send(Messages::RemoteRenderingBackendProxy::CreateImageBuffer(size, renderingMode, resolutionScale, colorSpace, m_imageBufferIdentifier), m_renderingBackendIdentifier); >+} >+ >+RemoteImageBuffer::~RemoteImageBuffer() >+{ >+ // Un-register itself as a MessageReceiver. >+ IPC::MessageReceiverMap& messageReceiverMap = WebProcess::singleton().ensureGPUProcessConnection().messageReceiverMap(); >+ messageReceiverMap.removeMessageReceiver(*this); >+ >+ // Release the RemoteImageBufferProxy. >+ send(Messages::RemoteRenderingBackendProxy::ReleaseImageBuffer(m_imageBufferIdentifier), m_renderingBackendIdentifier); >+} >+ >+IPC::Connection* RemoteImageBuffer::messageSenderConnection() const >+{ >+ return &WebProcess::singleton().ensureGPUProcessConnection().connection(); >+} >+ >+uint64_t RemoteImageBuffer::messageSenderDestinationID() const >+{ >+ return m_imageBufferIdentifier.toUInt64(); >+} >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.h b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8f7b0273d3c6cb9880b2f30a78cd0f074f6d22a2 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.h >@@ -0,0 +1,60 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "ImageBufferIdentifier.h" >+#include "MessageReceiver.h" >+#include "MessageSender.h" >+#include "RenderingBackendIdentifier.h" >+#include <WebCore/DisplayListItems.h> >+ >+namespace WebKit { >+ >+class RemoteImageBuffer >+ : private IPC::MessageSender >+ , private IPC::MessageReceiver { >+public: >+ ~RemoteImageBuffer(); >+ >+protected: >+ RemoteImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, float resolutionScale, WebCore::ColorSpace, RenderingBackendIdentifier); >+ >+ // IPC::MessageSender. >+ IPC::Connection* messageSenderConnection() const override; >+ uint64_t messageSenderDestinationID() const override; >+ >+ // IPC::MessageReceiver >+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; >+ >+ ImageBufferIdentifier m_imageBufferIdentifier { ImageBufferIdentifier::generate() }; >+ RenderingBackendIdentifier m_renderingBackendIdentifier; >+}; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.messages.in b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.messages.in >new file mode 100644 >index 0000000000000000000000000000000000000000..10a61fc4d4bdf2b20f4ef9d8bcf6d8f03e849229 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteImageBuffer.messages.in >@@ -0,0 +1,28 @@ >+# Copyright (C) 2020 Apple Inc. All rights reserved. >+# >+# Redistribution and use in source and binary forms, with or without >+# modification, are permitted provided that the following conditions >+# are met: >+# 1. Redistributions of source code must retain the above copyright >+# notice, this list of conditions and the following disclaimer. >+# 2. Redistributions in binary form must reproduce the above copyright >+# notice, this list of conditions and the following disclaimer in the >+# documentation and/or other materials provided with the distribution. >+# >+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND >+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR >+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR >+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER >+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, >+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ >+#if ENABLE(GPU_PROCESS) >+ >+messages -> RemoteImageBuffer NotRefCounted { >+} >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.cpp b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..80357b0a4b181398551fe90ae29e4b969d6a1878 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.cpp >@@ -0,0 +1,80 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RemoteRenderingBackend.h" >+ >+#if ENABLE(GPU_PROCESS) >+ >+ >+namespace WebKit { >+ >+using namespace WebCore; >+ >+std::unique_ptr<RenderingBackend> RemoteRenderingBackend::create() >+{ >+ return std::unique_ptr<RemoteRenderingBackend>(new RemoteRenderingBackend()); >+} >+ >+RemoteRenderingBackend::RemoteRenderingBackend() >+{ >+ // Create the RemoteRenderingBackendProxy. >+ send(Messages::GPUConnectionToWebProcess::CreateRenderingBackend(m_renderingBackendIdentifier), 0); >+} >+ >+RemoteRenderingBackend::~RemoteRenderingBackend() >+{ >+ // Release the RemoteRenderingBackendProxy. >+ send(Messages::GPUConnectionToWebProcess::ReleaseRenderingBackend(m_renderingBackendIdentifier), 0); >+} >+ >+IPC::Connection* RemoteRenderingBackend::messageSenderConnection() const >+{ >+ return &WebProcess::singleton().ensureGPUProcessConnection().connection(); >+} >+ >+uint64_t RemoteRenderingBackend::messageSenderDestinationID() const >+{ >+ return m_renderingBackendIdentifier.toUInt64(); >+} >+ >+std::unique_ptr<ImageBuffer> RemoteRenderingBackend::createImageBuffer(const FloatSize& size, RenderingMode renderingMode, float resolutionScale, ColorSpace colorSpace, const HostWindow* hostWindow) >+{ >+ std::unique_ptr<ImageBuffer> imageBuffer; >+ >+ switch (renderingMode) { >+ case RenderingMode::RemoteAccelerated: >+ case RenderingMode::Remote: >+ // FIXME: create the remote ImageBuffer. >+ default: >+ imageBuffer = RenderingBackend::createImageBuffer(size, renderingMode, resolutionScale, colorSpace, hostWindow); >+ } >+ >+ return imageBuffer; >+} >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.h b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..86be9dcbd60f395877f48e51718509d9d1f44c05 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/RemoteRenderingBackend.h >@@ -0,0 +1,60 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include "MessageReceiver.h" >+#include "MessageSender.h" >+#include "RenderingBackendIdentifier.h" >+#include <WebCore/RenderingBackend.h> >+ >+namespace WebKit { >+ >+class RemoteRenderingBackend >+ : public WebCore::RenderingBackend >+ , private IPC::MessageSender >+ , private IPC::MessageReceiver { >+public: >+ static std::unique_ptr<RenderingBackend> create(); >+ >+ ~RemoteRenderingBackend(); >+ >+ // IPC::MessageSender. >+ IPC::Connection* messageSenderConnection() const override; >+ uint64_t messageSenderDestinationID() const override; >+ >+ // RenderingBackend >+ std::unique_ptr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, float resolutionScale, WebCore::ColorSpace, const WebCore::HostWindow*) override; >+ >+private: >+ RemoteRenderingBackend(); >+ RenderingBackendIdentifier m_renderingBackendIdentifier { RenderingBackendIdentifier::generate() }; >+}; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/GPU/RenderingBackend/RenderingBackendIdentifier.h b/Source/WebKit/WebProcess/GPU/RenderingBackend/RenderingBackendIdentifier.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d235470ccfe7b79bb924578afb417035c913dd02 >--- /dev/null >+++ b/Source/WebKit/WebProcess/GPU/RenderingBackend/RenderingBackendIdentifier.h >@@ -0,0 +1,39 @@ >+/* >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(GPU_PROCESS) >+ >+#include <wtf/ObjectIdentifier.h> >+ >+namespace WebKit { >+ >+enum RenderingBackendIdentifierType { }; >+using RenderingBackendIdentifier = ObjectIdentifier<RenderingBackendIdentifierType>; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(GPU_PROCESS) >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp >index 8e4c9375d7b8cc10ffa00803d482173be5a3558a..7d7b886d686435d2bd1a1144c654606a743803f5 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp >@@ -90,6 +90,10 @@ > #include "VideoFullscreenManager.h" > #endif > >+#if ENABLE(GPU_PROCESS) >+#include "RemoteRenderingBackend.h" >+#endif >+ > #if ENABLE(ASYNC_SCROLLING) > #include "RemoteScrollingCoordinator.h" > #endif >@@ -891,6 +895,15 @@ RefPtr<DisplayRefreshMonitor> WebChromeClient::createDisplayRefreshMonitor(Platf > > #endif > >+std::unique_ptr<RenderingBackend> WebChromeClient::createRenderingBackend() const >+{ >+#if ENABLE(GPU_PROCESS) >+ return RemoteRenderingBackend::create(); >+#else >+ return RenderingBackend::create(); >+#endif >+} >+ > void WebChromeClient::attachRootGraphicsLayer(Frame&, GraphicsLayer* layer) > { > if (layer) >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h >index a8a4ccac57d808aaa55d8d7951bc5c541c60f2ad..56787e01700ebbee9dc37e3ab845866485f6d6d3 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h >@@ -233,6 +233,8 @@ private: > RefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(WebCore::PlatformDisplayID) const final; > #endif > >+ std::unique_ptr<WebCore::RenderingBackend> createRenderingBackend() const final; >+ > CompositingTriggerFlags allowedCompositingTriggers() const final > { > return static_cast<CompositingTriggerFlags>( >diff --git a/Source/WebKit/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit/WebProcess/WebPage/WebFrame.cpp >index 9fbb1fdf0d827884665cec7737b310b5031d40c5..0f8842900f851a7d92f886ca66f91a910e9fefaf 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebFrame.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebFrame.cpp >@@ -840,7 +840,7 @@ RefPtr<ShareableBitmap> WebFrame::createSelectionSnapshot() const > if (!snapshot) > return nullptr; > >- auto sharedSnapshot = ShareableBitmap::createShareable(snapshot->internalSize(), { }); >+ auto sharedSnapshot = ShareableBitmap::createShareable(snapshot->backendSize(), { }); > if (!sharedSnapshot) > return nullptr; > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 0a1a0ec9e3506cfc543d89f4c19bf1fda4b98291..e8af0620163f8bb0a84ba13e0ff82d0c2960000e 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,17 @@ >+2020-02-03 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ Create a new ImageBuffer type for drawing on a DisplayList >+ https://bugs.webkit.org/show_bug.cgi?id=207109 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ The extra recording happens because CanvasBase::setImageBuffer() used to >+ issue its GraphicsContext commands directly to the backend. With this >+ patch, DisplayListImageBuffer does not allow access to the backend context. >+ So all the GraphicsContext commands has to be recorded. >+ >+ * displaylists/canvas-display-list-expected.txt: >+ > 2020-02-03 Jason Lawrence <lawrence.j@apple.com> > > [ Mac wk2 ] http/wpt/mediarecorder/MediaRecorder-AV-audio-video-dataavailable-gpuprocess.html is flaky failing. >diff --git a/LayoutTests/displaylists/canvas-display-list-expected.txt b/LayoutTests/displaylists/canvas-display-list-expected.txt >index 1b57e791b72acca877614479b4dc7fe5c9594d77..34c87b9b0429455a9bf1141c6bfb3971c7520b8f 100644 >--- a/LayoutTests/displaylists/canvas-display-list-expected.txt >+++ b/LayoutTests/displaylists/canvas-display-list-expected.txt >@@ -1,7 +1,11 @@ > >+(save >+ (restore-index 0)) > (set-state >- (change-flags 256) >- (fill-color #C80000)) >+ (change-flags 1050912) >+ (stroke-thickness 1.00) >+ (fill-color #C80000) >+ (shadows-ignore-transforms 1)) > (fill-rect > (extent at (10,10) size 55x50) > (rect at (10,10) size 55x50))
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 207221
:
389695
|
389701
|
391709
|
391726
|
392081
|
392168