diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /vcl/inc/skia | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/inc/skia')
-rw-r--r-- | vcl/inc/skia/gdiimpl.hxx | 332 | ||||
-rw-r--r-- | vcl/inc/skia/salbmp.hxx | 134 | ||||
-rw-r--r-- | vcl/inc/skia/utils.hxx | 135 | ||||
-rw-r--r-- | vcl/inc/skia/win/gdiimpl.hxx | 102 | ||||
-rw-r--r-- | vcl/inc/skia/x11/gdiimpl.hxx | 48 | ||||
-rw-r--r-- | vcl/inc/skia/x11/salvd.hxx | 46 | ||||
-rw-r--r-- | vcl/inc/skia/x11/textrender.hxx | 40 | ||||
-rw-r--r-- | vcl/inc/skia/zone.hxx | 30 |
8 files changed, 867 insertions, 0 deletions
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx new file mode 100644 index 000000000..ca227e4e8 --- /dev/null +++ b/vcl/inc/skia/gdiimpl.hxx @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_SKIA_GDIIMPL_HXX +#define INCLUDED_VCL_SKIA_GDIIMPL_HXX + +#include <vcl/dllapi.h> + +#include <salgdiimpl.hxx> +#include <salgeom.hxx> + +#include <SkSurface.h> +#include <SkRegion.h> + +#include <prewin.h> +#include <tools/sk_app/WindowContext.h> +#include <postwin.h> + +class SkiaFlushIdle; +class GenericSalLayout; +class SkFont; +class SkiaSalBitmap; + +class VCL_DLLPUBLIC SkiaSalGraphicsImpl : public SalGraphicsImpl +{ +public: + SkiaSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider* pProvider); + virtual ~SkiaSalGraphicsImpl() override; + + virtual void Init() override; + + virtual void DeInit() override; + + virtual OUString getRenderBackendName() const override { return "skia"; } + + const vcl::Region& getClipRegion() const; + virtual bool setClipRegion(const vcl::Region&) override; + + // + // get the depth of the device + virtual sal_uInt16 GetBitCount() const override; + + // get the width of the device + virtual long GetGraphicsWidth() const override; + + // set the clip region to empty + virtual void ResetClipRegion() override; + + // set the line color to transparent (= don't draw lines) + + virtual void SetLineColor() override; + + // set the line color to a specific color + virtual void SetLineColor(Color nColor) override; + + // set the fill color to transparent (= don't fill) + virtual void SetFillColor() override; + + // set the fill color to a specific color, shapes will be + // filled accordingly + virtual void SetFillColor(Color nColor) override; + + // enable/disable XOR drawing + virtual void SetXORMode(bool bSet, bool bInvertOnly) override; + + // set line color for raster operations + virtual void SetROPLineColor(SalROPColor nROPColor) override; + + // set fill color for raster operations + virtual void SetROPFillColor(SalROPColor nROPColor) override; + + // draw --> LineColor and FillColor and RasterOp and ClipRegion + virtual void drawPixel(long nX, long nY) override; + virtual void drawPixel(long nX, long nY, Color nColor) override; + + virtual void drawLine(long nX1, long nY1, long nX2, long nY2) override; + + virtual void drawRect(long nX, long nY, long nWidth, long nHeight) override; + + virtual void drawPolyLine(sal_uInt32 nPoints, const SalPoint* pPtAry) override; + + virtual void drawPolygon(sal_uInt32 nPoints, const SalPoint* pPtAry) override; + + virtual void drawPolyPolygon(sal_uInt32 nPoly, const sal_uInt32* pPoints, + PCONSTSALPOINT* pPtAry) override; + + virtual bool drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolyPolygon&, double fTransparency) override; + + virtual bool drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDevice, + const basegfx::B2DPolygon&, double fTransparency, double fLineWidth, + const std::vector<double>* pStroke, basegfx::B2DLineJoin, + css::drawing::LineCap, double fMiterMinimumAngle, + bool bPixelSnapHairline) override; + + virtual bool drawPolyLineBezier(sal_uInt32 nPoints, const SalPoint* pPtAry, + const PolyFlags* pFlgAry) override; + + virtual bool drawPolygonBezier(sal_uInt32 nPoints, const SalPoint* pPtAry, + const PolyFlags* pFlgAry) override; + + virtual bool drawPolyPolygonBezier(sal_uInt32 nPoly, const sal_uInt32* pPoints, + const SalPoint* const* pPtAry, + const PolyFlags* const* pFlgAry) override; + + // CopyArea --> No RasterOp, but ClipRegion + virtual void copyArea(long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth, + long nSrcHeight, bool bWindowInvalidate) override; + + virtual void copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics) override; + + virtual bool blendBitmap(const SalTwoRect&, const SalBitmap& rBitmap) override; + + virtual bool blendAlphaBitmap(const SalTwoRect&, const SalBitmap& rSrcBitmap, + const SalBitmap& rMaskBitmap, + const SalBitmap& rAlphaBitmap) override; + + virtual void drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) override; + + virtual void drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, + const SalBitmap& rMaskBitmap) override; + + virtual void drawMask(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, + Color nMaskColor) override; + + virtual std::shared_ptr<SalBitmap> getBitmap(long nX, long nY, long nWidth, + long nHeight) override; + + virtual Color getPixel(long nX, long nY) override; + + // invert --> ClipRegion (only Windows or VirDevs) + virtual void invert(long nX, long nY, long nWidth, long nHeight, SalInvert nFlags) override; + + virtual void invert(sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags) override; + + virtual bool drawEPS(long nX, long nY, long nWidth, long nHeight, void* pPtr, + sal_uInt32 nSize) override; + + /** Render bitmap with alpha channel + + @param rSourceBitmap + Source bitmap to blit + + @param rAlphaBitmap + Alpha channel to use for blitting + + @return true, if the operation succeeded, and false + otherwise. In this case, clients should try to emulate alpha + compositing themselves + */ + virtual bool drawAlphaBitmap(const SalTwoRect&, const SalBitmap& rSourceBitmap, + const SalBitmap& rAlphaBitmap) override; + + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ + virtual bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) override; + + /** Render solid rectangle with given transparency + + @param nX Top left coordinate of rectangle + + @param nY Bottom right coordinate of rectangle + + @param nWidth Width of rectangle + + @param nHeight Height of rectangle + + @param nTransparency Transparency value (0-255) to use. 0 blits and opaque, 255 a + fully transparent rectangle + + @returns true if successfully drawn, false if not able to draw rectangle + */ + virtual bool drawAlphaRect(long nX, long nY, long nWidth, long nHeight, + sal_uInt8 nTransparency) override; + + virtual bool drawGradient(const tools::PolyPolygon& rPolygon, + const Gradient& rGradient) override; + + virtual bool supportsOperation(OutDevSupportType eType) const override; + +#ifdef DBG_UTIL + void dump(const char* file) const; +#endif + + // Default blend mode for SkPaint is SkBlendMode::kSrcOver + void drawImage(const SalTwoRect& rPosAry, const sk_sp<SkImage>& aImage, + SkBlendMode eBlendMode = SkBlendMode::kSrcOver); + + void drawShader(const SalTwoRect& rPosAry, const sk_sp<SkShader>& shader); + + enum class GlyphOrientation + { + Apply, + Ignore + }; + void drawGenericLayout(const GenericSalLayout& layout, Color textColor, const SkFont& font, + GlyphOrientation glyphOrientation); + +protected: + // To be called before any drawing. + void preDraw(); + // To be called after any drawing. + void postDraw(); + // The canvas to draw to. Will be diverted to a temporary for Xor mode. + SkCanvas* getDrawCanvas() { return mXorMode ? getXorCanvas() : mSurface->getCanvas(); } + // Call before makeImageSnapshot(), ensures the content is up to date. + void flushDrawing(); + + virtual void createSurface(); + // Call to ensure that mSurface is valid. If mSurface is going to be modified, + // use preDraw() instead of this. + void checkSurface(); + void destroySurface(); + // Reimplemented for X11. + virtual bool avoidRecreateByResize() const { return false; } + void createWindowSurface(bool forceRaster = false); + virtual void createWindowContext(bool forceRaster = false) = 0; + void createOffscreenSurface(); + + void privateDrawAlphaRect(long nX, long nY, long nWidth, long nHeight, double nTransparency, + bool blockAA = false); + + void setProvider(SalGeometryProvider* provider) { mProvider = provider; } + + bool isOffscreen() const { return mProvider == nullptr || mProvider->IsOffScreen(); } + bool isGPU() const { return mIsGPU; } + + void invert(basegfx::B2DPolygon const& rPoly, SalInvert eFlags); + + // Called by SkiaFlushIdle. + virtual void performFlush() = 0; + void scheduleFlush(); + friend class SkiaFlushIdle; + + // get the width of the device + int GetWidth() const { return mProvider ? mProvider->GetWidth() : 1; } + // get the height of the device + int GetHeight() const { return mProvider ? mProvider->GetHeight() : 1; } + + SkCanvas* getXorCanvas(); + void applyXor(); + // NOTE: This must be called before the operation does any drawing. + void addXorRegion(const SkRect& rect) + { + if (mXorMode) + { + // Make slightly larger, just in case (rounding, antialiasing,...). + SkIRect addedRect = rect.makeOutset(2, 2).round(); + // Two xor operations should cancel each other out. We batch xor operations, + // but if they can overlap, apply xor now, since applyXor() does the operation + // just once. + if (mXorRegion.intersects(addedRect)) + applyXor(); + mXorRegion.op(addedRect, SkRegion::kUnion_Op); + } + } + static void setCanvasClipRegion(SkCanvas* canvas, const vcl::Region& region); + sk_sp<SkImage> mergeCacheBitmaps(const SkiaSalBitmap& bitmap, const SkiaSalBitmap* alphaBitmap, + const Size targetSize); + + // Skia uses floating point coordinates, so when we use integer coordinates, sometimes + // rounding results in off-by-one errors (down), especially when drawing using GPU, + // see https://bugs.chromium.org/p/skia/issues/detail?id=9611 . Compensate for + // it by using centers of pixels. Using 0.5 may sometimes round up, so go with 0.495 . + static constexpr SkScalar toSkX(long x) { return x + 0.495; } + static constexpr SkScalar toSkY(long y) { return y + 0.495; } + // Value to add to be exactly in the middle of the pixel. + static constexpr SkScalar toSkXYFix = SkScalar(0.005); + + // Perform any pending drawing such as delayed merging of polygons. Called by preDraw() + // and anything that means the next operation cannot be another one in a series (e.g. + // changing colors). + void checkPendingDrawing(); + bool delayDrawPolyPolygon(const basegfx::B2DPolyPolygon& polygon, double transparency); + void performDrawPolyPolygon(const basegfx::B2DPolyPolygon& polygon, double transparency, + bool useAA); + + template <typename charT, typename traits> + friend inline std::basic_ostream<charT, traits>& + operator<<(std::basic_ostream<charT, traits>& stream, const SkiaSalGraphicsImpl* graphics) + { // O - offscreen, G - GPU-based, R - raster + return stream << static_cast<const void*>(graphics) << " " + << Size(graphics->GetWidth(), graphics->GetHeight()) + << (graphics->isGPU() ? "G" : "R") << (graphics->isOffscreen() ? "O" : ""); + } + + SalGraphics& mParent; + /// Pointer to the SalFrame or SalVirtualDevice + SalGeometryProvider* mProvider; + std::unique_ptr<sk_app::WindowContext> mWindowContext; + // The Skia surface that is target of all the rendering. + sk_sp<SkSurface> mSurface; + bool mIsGPU; // whether the surface is GPU-backed + // Keep reference to shared GrContext. + vcl::Region mClipRegion; + Color mLineColor; + Color mFillColor; + bool mXorMode; + SkBitmap mXorBitmap; + std::unique_ptr<SkCanvas> mXorCanvas; + SkRegion mXorRegion; // the area that needs updating for the xor operation + std::unique_ptr<SkiaFlushIdle> mFlush; + // Info about pending polygons to draw (we try to merge adjacent polygons into one). + struct LastPolyPolygonInfo + { + basegfx::B2DPolyPolygonVector polygons; + basegfx::B2DRange bounds; + double transparency; + }; + LastPolyPolygonInfo mLastPolyPolygonInfo; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx new file mode 100644 index 000000000..5079be088 --- /dev/null +++ b/vcl/inc/skia/salbmp.hxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_SKIA_SALBMP_H +#define INCLUDED_VCL_INC_SKIA_SALBMP_H + +#include <salbmp.hxx> + +#include <SkImage.h> + +#include <boost/shared_ptr.hpp> + +class VCL_PLUGIN_PUBLIC SkiaSalBitmap final : public SalBitmap +{ +public: + SkiaSalBitmap(); + SkiaSalBitmap(const sk_sp<SkImage>& image); + virtual ~SkiaSalBitmap() override; + + // SalBitmap methods + virtual bool Create(const Size& rSize, sal_uInt16 nBitCount, + const BitmapPalette& rPal) override; + virtual bool Create(const SalBitmap& rSalBmp) override; + virtual bool Create(const SalBitmap& rSalBmp, SalGraphics* pGraphics) override; + virtual bool Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount) override; + virtual bool Create(const css::uno::Reference<css::rendering::XBitmapCanvas>& rBitmapCanvas, + Size& rSize, bool bMask = false) override; + + virtual void Destroy() final override; + + virtual Size GetSize() const override; + virtual sal_uInt16 GetBitCount() const override; + + virtual BitmapBuffer* AcquireBuffer(BitmapAccessMode nMode) override; + virtual void ReleaseBuffer(BitmapBuffer* pBuffer, BitmapAccessMode nMode) override; + + virtual bool GetSystemData(BitmapSystemData& rData) override; + + virtual bool ScalingSupported() const override; + virtual bool Scale(const double& rScaleX, const double& rScaleY, + BmpScaleFlag nScaleFlag) override; + virtual bool Replace(const Color& rSearchColor, const Color& rReplaceColor, + sal_uInt8 nTol) override; + virtual bool InterpretAs8Bit() override; + virtual bool ConvertToGreyscale() override; + + const BitmapPalette& Palette() const { return mPalette; } + // Returns the contents as SkImage (possibly GPU-backed). + const sk_sp<SkImage>& GetSkImage() const; + + // Returns the contents as alpha SkImage (possibly GPU-backed) + const sk_sp<SkImage>& GetAlphaSkImage() const; + +#ifdef DBG_UTIL + void dump(const char* file) const; +#endif + +private: + // Reset the cached images allocated in GetSkImage()/GetAlphaSkImage(). + void ResetCachedData(); + // Sets the data only as SkImage (will be converted as needed). + void ResetToSkImage(sk_sp<SkImage> image); + // Resets all data that does not match mSize. + void ResetCachedDataBySize(); + // Call to ensure mBuffer has data (will convert from mImage if necessary). + void EnsureBitmapData(); + void EnsureBitmapData() const { return const_cast<SkiaSalBitmap*>(this)->EnsureBitmapData(); } + // Like EnsureBitmapData(), but will also make any shared data unique. + // Call before changing the data. + void EnsureBitmapUniqueData(); + // Allocate mBuffer (with uninitialized contents). + bool CreateBitmapData(); + SkBitmap GetAsSkBitmap() const; +#ifdef DBG_UTIL + void verify() const; +#else + void verify() const {}; +#endif + + template <typename charT, typename traits> + friend inline std::basic_ostream<charT, traits>& + operator<<(std::basic_ostream<charT, traits>& stream, const SkiaSalBitmap* bitmap) + { + // I/i - has SkImage (on GPU/CPU), + // A/a - has alpha SkImage (on GPU/CPU) + return stream << static_cast<const void*>(bitmap) << " " << bitmap->GetSize() << "/" + << (bitmap->mImage ? (bitmap->mImage->isTextureBacked() ? "I" : "i") : "") + << (bitmap->mAlphaImage ? (bitmap->mAlphaImage->isTextureBacked() ? "A" : "a") + : ""); + } + + BitmapPalette mPalette; + int mBitCount = 0; // bpp + Size mSize; + // The contents of the bitmap may be stored in several different ways: + // As mBuffer buffer, which normally stores pixels in the given format. + // As SkImage, as cached GPU-backed data, but sometimes also a result of some operation. + // There is no "master" storage that the other would be derived from. The usual + // mode of operation is that mBuffer holds the data, mImage is created + // on demand as GPU-backed cached data by calling GetSkImage(), and the cached mImage + // is reset by ResetCachedImage(). But sometimes only mImage will be set and in that case + // mBuffer must be filled from it on demand if necessary by EnsureBitmapData(). + boost::shared_ptr<sal_uInt8[]> mBuffer; + int mScanlineSize; // size of one row in mBuffer + sk_sp<SkImage> mImage; // possibly GPU-backed + sk_sp<SkImage> mAlphaImage; // cached contents as alpha image, possibly GPU-backed + // Actual scaling triggered by scale() is done on-demand. This is the size of the pixel + // data in mBuffer, if it differs from mSize, then there is a scaling operation pending. + Size mPixelsSize; + SkFilterQuality mScaleQuality = kHigh_SkFilterQuality; // quality for on-demand scaling +#ifdef DBG_UTIL + int mWriteAccessCount = 0; // number of write AcquireAccess() that have not been released +#endif +}; + +#endif // INCLUDED_VCL_INC_SKIA_SALBMP_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/utils.hxx b/vcl/inc/skia/utils.hxx new file mode 100644 index 000000000..a43ff8f58 --- /dev/null +++ b/vcl/inc/skia/utils.hxx @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_SKIA_UTILS_H +#define INCLUDED_VCL_INC_SKIA_UTILS_H + +#include <vcl/skia/SkiaHelper.hxx> + +#include <tools/gen.hxx> +#include <driverblocklist.hxx> + +#include <SkRegion.h> +#include <tools/sk_app/VulkanWindowContext.h> + +namespace SkiaHelper +{ +// Get the one shared GrContext instance. +GrContext* getSharedGrContext(); + +void disableRenderMethod(RenderMethod method); + +// Create SkSurface, GPU-backed if possible. +VCL_DLLPUBLIC sk_sp<SkSurface> createSkSurface(int width, int height, + SkColorType type = kN32_SkColorType); + +inline sk_sp<SkSurface> createSkSurface(const Size& size, SkColorType type = kN32_SkColorType) +{ + return createSkSurface(size.Width(), size.Height(), type); +} + +// Create SkImage, GPU-backed if possible. +VCL_DLLPUBLIC sk_sp<SkImage> createSkImage(const SkBitmap& bitmap); + +// Call surface->makeImageSnapshot() and abort on failure. +VCL_DLLPUBLIC sk_sp<SkImage> makeCheckedImageSnapshot(sk_sp<SkSurface> surface); +VCL_DLLPUBLIC sk_sp<SkImage> makeCheckedImageSnapshot(sk_sp<SkSurface> surface, + const SkIRect& bounds); + +// Must be called in any VCL backend before any Skia functionality is used. +// If not set, Skia will be disabled. +VCL_DLLPUBLIC void + prepareSkia(std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContext)(bool)); + +// Shared cache of images. +void addCachedImage(const OString& key, sk_sp<SkImage> image); +sk_sp<SkImage> findCachedImage(const OString& key); +void removeCachedImage(sk_sp<SkImage> image); + +#ifdef DBG_UTIL +void prefillSurface(sk_sp<SkSurface>& surface); +VCL_DLLPUBLIC void dump(const SkBitmap& bitmap, const char* file); +VCL_DLLPUBLIC void dump(const sk_sp<SkImage>& image, const char* file); +VCL_DLLPUBLIC void dump(const sk_sp<SkSurface>& surface, const char* file); +#endif + +extern uint32_t vendorId; + +inline DriverBlocklist::DeviceVendor getVendor() +{ + return DriverBlocklist::GetVendorFromId(vendorId); +} + +} // namespace + +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const SkRect& rectangle) +{ + if (rectangle.isEmpty()) + return stream << "EMPTY"; + else + return stream << rectangle.width() << 'x' << rectangle.height() << "@(" << rectangle.x() + << ',' << rectangle.y() << ")"; +} + +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const SkIRect& rectangle) +{ + if (rectangle.isEmpty()) + return stream << "EMPTY"; + else + return stream << rectangle.width() << 'x' << rectangle.height() << "@(" << rectangle.x() + << ',' << rectangle.y() << ")"; +} + +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const SkRegion& region) +{ + if (region.isEmpty()) + return stream << "EMPTY"; + stream << "("; + SkRegion::Iterator it(region); + for (int i = 0; !it.done(); it.next(), ++i) + stream << "[" << i << "] " << it.rect(); + stream << ")"; + return stream; +} + +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const SkImage& image) +{ + // G - on GPU + return stream << static_cast<const void*>(&image) << " " << Size(image.width(), image.height()) + << "/" << (SkColorTypeBytesPerPixel(image.imageInfo().colorType()) * 8) + << (image.isTextureBacked() ? "G" : ""); +} +template <typename charT, typename traits> +inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream, + const sk_sp<SkImage>& image) +{ + return stream << *image; +} + +#endif // INCLUDED_VCL_INC_SKIA_UTILS_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx new file mode 100644 index 000000000..564fcd7e9 --- /dev/null +++ b/vcl/inc/skia/win/gdiimpl.hxx @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_SKIA_WIN_GDIIMPL_HXX +#define INCLUDED_VCL_INC_SKIA_WIN_GDIIMPL_HXX + +#include <memory> +#include <vcl/dllapi.h> + +#include <skia/gdiimpl.hxx> +#include <win/salgdi.h> +#include <win/wingdiimpl.hxx> +#include <o3tl/lru_map.hxx> +#include <ControlCacheKey.hxx> +#include <svdata.hxx> + +#include <SkFont.h> + +class SkTypeface; +class SkFontMgr; +class ControlCacheKey; + +class SkiaCompatibleDC : public CompatibleDC +{ +public: + SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height); + + virtual std::unique_ptr<Texture> getAsMaskTexture() const override; + + sk_sp<SkImage> getAsImage() const; + sk_sp<SkImage> getAsMaskImage() const; + sk_sp<SkImage> getAsImageDiff(const SkiaCompatibleDC& white) const; + + struct Texture; +}; + +struct SkiaCompatibleDC::Texture : public CompatibleDC::Texture +{ + sk_sp<SkImage> image; + virtual bool isValid() const { return image.get(); } + virtual int GetWidth() const { return image->width(); } + virtual int GetHeight() const { return image->height(); } +}; + +class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl, public WinSalGraphicsImplBase +{ +private: + WinSalGraphics& mWinParent; + +public: + WinSkiaSalGraphicsImpl(WinSalGraphics& rGraphics, SalGeometryProvider* mpProvider); + + virtual void DeInit() override; + virtual void freeResources() override; + + virtual bool UseRenderNativeControl() const override { return true; } + virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX, + int nY) override; + virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX, + int nY, ControlCacheKey& aControlCacheKey) override; + + virtual bool DrawTextLayout(const GenericSalLayout& layout) override; + virtual void ClearDevFontCache() override; + + static void prepareSkia(); + +protected: + virtual void createWindowContext(bool forceRaster = false) override; + virtual void performFlush() override; + sk_sp<SkTypeface> createDirectWriteTypeface(const LOGFONTW& logFont); + SkFont::Edging getFontEdging(); + IDWriteFactory* dwriteFactory; + IDWriteGdiInterop* dwriteGdiInterop; + sk_sp<SkFontMgr> dwriteFontMgr; + bool dwriteDone = false; + SkFont::Edging fontEdging; + bool fontEdgingDone = false; +}; + +typedef std::pair<ControlCacheKey, sk_sp<SkImage>> SkiaControlCachePair; +typedef o3tl::lru_map<ControlCacheKey, sk_sp<SkImage>, ControlCacheHashFunction> + SkiaControlCacheType; + +class SkiaControlsCache +{ + SkiaControlCacheType cache; + + SkiaControlsCache(); + +public: + static SkiaControlCacheType& get(); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/x11/gdiimpl.hxx b/vcl/inc/skia/x11/gdiimpl.hxx new file mode 100644 index 000000000..d131d54bf --- /dev/null +++ b/vcl/inc/skia/x11/gdiimpl.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_SKIA_X11_GDIIMPL_HXX +#define INCLUDED_VCL_INC_SKIA_X11_GDIIMPL_HXX + +#include <vcl/dllapi.h> + +#include <unx/salgdi.h> +#include <unx/x11/x11gdiimpl.h> +#include <skia/gdiimpl.hxx> +#include <skia/utils.hxx> + +class VCL_PLUGIN_PUBLIC X11SkiaSalGraphicsImpl final : public SkiaSalGraphicsImpl, + public X11GraphicsImpl +{ +private: + X11SalGraphics& mX11Parent; + +public: + X11SkiaSalGraphicsImpl(X11SalGraphics& rParent); + virtual ~X11SkiaSalGraphicsImpl() override; + + virtual void Init() override; + virtual void DeInit() override; + virtual void freeResources() override; + + static void prepareSkia(); + +private: + virtual void createWindowContext(bool forceRaster = false) override; + virtual void performFlush() override; + virtual bool avoidRecreateByResize() const override; + static std::unique_ptr<sk_app::WindowContext> + createWindowContext(Display* display, Drawable drawable, const XVisualInfo* visual, int width, + int height, SkiaHelper::RenderMethod renderMethod, bool temporary); + friend std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext(bool); +}; + +#endif // INCLUDED_VCL_INC_SKIA_X11_GDIIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/x11/salvd.hxx b/vcl/inc/skia/x11/salvd.hxx new file mode 100644 index 000000000..8ff75175d --- /dev/null +++ b/vcl/inc/skia/x11/salvd.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_SKIA_X11_SALVD_H +#define INCLUDED_VCL_INC_SKIA_X11_SALVD_H + +#include <salvd.hxx> + +class X11SkiaSalVirtualDevice : public SalVirtualDevice +{ + SalDisplay* mpDisplay; + std::unique_ptr<X11SalGraphics> mpGraphics; + bool mbGraphics; // is Graphics used + SalX11Screen mnXScreen; + int mnWidth; + int mnHeight; + +public: + X11SkiaSalVirtualDevice(SalGraphics const* pGraphics, long nDX, long nDY, + const SystemGraphicsData* pData, + std::unique_ptr<X11SalGraphics> pNewGraphics); + virtual ~X11SkiaSalVirtualDevice() override; + + // SalGeometryProvider + virtual long GetWidth() const override { return mnWidth; } + virtual long GetHeight() const override { return mnHeight; } + + SalDisplay* GetDisplay() const { return mpDisplay; } + const SalX11Screen& GetXScreenNumber() const { return mnXScreen; } + + virtual SalGraphics* AcquireGraphics() override; + virtual void ReleaseGraphics(SalGraphics* pGraphics) override; + + // Set new size, without saving the old contents + virtual bool SetSize(long nNewDX, long nNewDY) override; +}; + +#endif // INCLUDED_VCL_INC_SKIA_X11_SALVD_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/x11/textrender.hxx b/vcl/inc/skia/x11/textrender.hxx new file mode 100644 index 000000000..d6eda9a04 --- /dev/null +++ b/vcl/inc/skia/x11/textrender.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_SKIA_TEXTRENDER_HXX +#define INCLUDED_VCL_INC_SKIA_TEXTRENDER_HXX + +#include <unx/freetypetextrender.hxx> + +#include <SkFontMgr.h> +#include <SkFontMgr_fontconfig.h> + +class VCL_DLLPUBLIC SkiaTextRender final : public FreeTypeTextRenderImpl +{ +public: + virtual void DrawTextLayout(const GenericSalLayout&, const SalGraphics&) override; + virtual void ClearDevFontCache() override; + +private: + sk_sp<SkFontMgr> fontManager; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/skia/zone.hxx b/vcl/inc/skia/zone.hxx new file mode 100644 index 000000000..1f6bbb0dd --- /dev/null +++ b/vcl/inc/skia/zone.hxx @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_INC_SKIA_ZONE_H +#define INCLUDED_VCL_INC_SKIA_ZONE_H + +#include <comphelper/crashzone.hxx> + +#include <vcl/dllapi.h> + +// Used around calls to Skia code to detect crashes in drivers. +class VCL_DLLPUBLIC SkiaZone : public CrashZone<SkiaZone> +{ +public: + static void hardDisable(); + static void relaxWatchdogTimings(); + static const CrashWatchdogTimingsValues& getCrashWatchdogTimingsValues(); + static void checkDebug(int nUnchanged, const CrashWatchdogTimingsValues& aTimingValues); + static const char* name() { return "Skia"; } +}; + +#endif // INCLUDED_VCL_INC_SKIA_ZONE_H + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |