LibreOffice Module vcl (master)  1
utils.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_VCL_INC_SKIA_UTILS_H
21 #define INCLUDED_VCL_INC_SKIA_UTILS_H
22 
23 #include <vcl/skia/SkiaHelper.hxx>
24 
25 #include <tools/gen.hxx>
26 #include <driverblocklist.hxx>
27 #include <vcl/bitmap.hxx>
28 #include <vcl/salgtype.hxx>
29 
30 #include <SkRegion.h>
31 #include <SkSurface.h>
32 #include <tools/sk_app/VulkanWindowContext.h>
33 
34 namespace SkiaHelper
35 {
36 // Get the one shared GrDirectContext instance.
37 GrDirectContext* getSharedGrDirectContext();
38 
39 void disableRenderMethod(RenderMethod method);
40 
41 // Create SkSurface, GPU-backed if possible.
42 VCL_DLLPUBLIC sk_sp<SkSurface> createSkSurface(int width, int height,
43  SkColorType type = kN32_SkColorType,
44  SkAlphaType alpha = kPremul_SkAlphaType);
45 
46 inline sk_sp<SkSurface> createSkSurface(const Size& size, SkColorType type = kN32_SkColorType,
47  SkAlphaType alpha = kPremul_SkAlphaType)
48 {
49  return createSkSurface(size.Width(), size.Height(), type, alpha);
50 }
51 
52 inline sk_sp<SkSurface> createSkSurface(int width, int height, SkAlphaType alpha)
53 {
54  return createSkSurface(width, height, kN32_SkColorType, alpha);
55 }
56 
57 inline sk_sp<SkSurface> createSkSurface(const Size& size, SkAlphaType alpha)
58 {
59  return createSkSurface(size.Width(), size.Height(), kN32_SkColorType, alpha);
60 }
61 
62 // Create SkImage, GPU-backed if possible.
63 VCL_DLLPUBLIC sk_sp<SkImage> createSkImage(const SkBitmap& bitmap);
64 
65 // Call surface->makeImageSnapshot() and abort on failure.
66 VCL_DLLPUBLIC sk_sp<SkImage> makeCheckedImageSnapshot(sk_sp<SkSurface> surface);
67 VCL_DLLPUBLIC sk_sp<SkImage> makeCheckedImageSnapshot(sk_sp<SkSurface> surface,
68  const SkIRect& bounds);
69 
70 inline Size imageSize(const sk_sp<SkImage>& image) { return Size(image->width(), image->height()); }
71 
72 // Must be called in any VCL backend before any Skia functionality is used.
73 // If not set, Skia will be disabled.
74 VCL_DLLPUBLIC void
75  prepareSkia(std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContext)(bool));
76 
77 // Shared cache of images.
78 void addCachedImage(const OString& key, sk_sp<SkImage> image);
79 sk_sp<SkImage> findCachedImage(const OString& key);
80 void removeCachedImage(sk_sp<SkImage> image);
82 
83 // SkSurfaceProps to be used by all Skia surfaces.
84 VCL_DLLPUBLIC const SkSurfaceProps* surfaceProps();
85 // Set pixel geometry to be used by SkSurfaceProps.
86 VCL_DLLPUBLIC void setPixelGeometry(SkPixelGeometry pixelGeometry);
87 
88 // Normal scaling algorithms have a poor quality when downscaling a lot.
89 // https://bugs.chromium.org/p/skia/issues/detail?id=11810 suggests to use mipmaps
90 // in such a case, which is annoying to do explicitly instead of Skia deciding which
91 // algorithm would be the best, but now with Skia removing SkFilterQuality and requiring
92 // explicitly being told what algorithm to use this appears to be the best we can do.
93 // Anything scaled down at least this ratio will use linear+mipmaps.
94 constexpr int downscaleRatioThreshold = 4;
95 
96 inline SkSamplingOptions makeSamplingOptions(BmpScaleFlag scaling, const SkMatrix& matrix)
97 {
98  switch (scaling)
99  {
101  if (matrix.getScaleX() <= 1.0 / downscaleRatioThreshold
102  || matrix.getScaleY() <= 1.0 / downscaleRatioThreshold)
103  return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
104  return SkSamplingOptions(SkCubicResampler::Mitchell());
106  return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
107  case BmpScaleFlag::Fast:
108  return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
109  default:
110  assert(false);
111  return SkSamplingOptions();
112  }
113 }
114 
115 inline SkSamplingOptions makeSamplingOptions(BmpScaleFlag scaling, const Size& srcSize,
116  const Size& destSize)
117 {
118  switch (scaling)
119  {
121  if (srcSize.Width() / destSize.Width() >= downscaleRatioThreshold
122  || srcSize.Height() / destSize.Height() >= downscaleRatioThreshold)
123  return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
124  return SkSamplingOptions(SkCubicResampler::Mitchell());
126  return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
127  case BmpScaleFlag::Fast:
128  return SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
129  default:
130  assert(false);
131  return SkSamplingOptions();
132  }
133 }
134 
135 inline SkSamplingOptions makeSamplingOptions(const SalTwoRect& rPosAry)
136 {
137  if (rPosAry.mnSrcWidth != rPosAry.mnDestWidth || rPosAry.mnSrcHeight != rPosAry.mnDestHeight)
138  {
139  if (rPosAry.mnSrcWidth / rPosAry.mnDestWidth >= downscaleRatioThreshold
140  || rPosAry.mnSrcHeight / rPosAry.mnDestHeight >= downscaleRatioThreshold)
141  return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
142  return SkSamplingOptions(SkCubicResampler::Mitchell()); // best
143  }
144  return SkSamplingOptions(); // none
145 }
146 
147 #ifdef DBG_UTIL
148 void prefillSurface(const sk_sp<SkSurface>& surface);
149 VCL_DLLPUBLIC void dump(const SkBitmap& bitmap, const char* file);
150 VCL_DLLPUBLIC void dump(const sk_sp<SkImage>& image, const char* file);
151 VCL_DLLPUBLIC void dump(const sk_sp<SkSurface>& surface, const char* file);
152 #endif
153 
154 VCL_DLLPUBLIC extern uint32_t vendorId;
155 
157 {
158  return DriverBlocklist::GetVendorFromId(vendorId);
159 }
160 
161 } // namespace SkiaHelper
162 
163 // For unittests.
164 namespace SkiaTests
165 {
166 VCL_DLLPUBLIC bool matrixNeedsHighQuality(const SkMatrix& matrix);
167 }
168 
169 template <typename charT, typename traits>
170 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
171  const SkRect& rectangle)
172 {
173  if (rectangle.isEmpty())
174  return stream << "EMPTY";
175  else
176  return stream << rectangle.width() << 'x' << rectangle.height() << "@(" << rectangle.x()
177  << ',' << rectangle.y() << ")";
178 }
179 
180 template <typename charT, typename traits>
181 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
182  const SkIRect& rectangle)
183 {
184  if (rectangle.isEmpty())
185  return stream << "EMPTY";
186  else
187  return stream << rectangle.width() << 'x' << rectangle.height() << "@(" << rectangle.x()
188  << ',' << rectangle.y() << ")";
189 }
190 
191 template <typename charT, typename traits>
192 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
193  const SkRegion& region)
194 {
195  if (region.isEmpty())
196  return stream << "EMPTY";
197  stream << "(";
198  SkRegion::Iterator it(region);
199  for (int i = 0; !it.done(); it.next(), ++i)
200  stream << "[" << i << "] " << it.rect();
201  stream << ")";
202  return stream;
203 }
204 
205 template <typename charT, typename traits>
206 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
207  const SkMatrix& matrix)
208 {
209  return stream << "[" << matrix[0] << " " << matrix[1] << " " << matrix[2] << "]"
210  << "[" << matrix[3] << " " << matrix[4] << " " << matrix[5] << "]"
211  << "[" << matrix[6] << " " << matrix[7] << " " << matrix[8] << "]";
212 }
213 
214 template <typename charT, typename traits>
215 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
216  const SkImage& image)
217 {
218  // G - on GPU
219  return stream << static_cast<const void*>(&image) << " " << Size(image.width(), image.height())
220  << "/" << (SkColorTypeBytesPerPixel(image.imageInfo().colorType()) * 8)
221  << (image.isTextureBacked() ? "G" : "");
222 }
223 template <typename charT, typename traits>
224 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
225  const sk_sp<SkImage>& image)
226 {
227  if (image == nullptr)
228  return stream << "(null)";
229  return stream << *image;
230 }
231 
232 #endif // INCLUDED_VCL_INC_SKIA_UTILS_H
233 
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
GrDirectContext * getSharedGrDirectContext()
VCL_DLLPUBLIC sk_sp< SkImage > makeCheckedImageSnapshot(sk_sp< SkSurface > surface)
#define VCL_DLLPUBLIC
Definition: dllapi.h:29
long Long
Size imageSize(const sk_sp< SkImage > &image)
Definition: utils.hxx:70
VCL_DLLPUBLIC const SkSurfaceProps * surfaceProps()
VCL_DLLPUBLIC void setPixelGeometry(SkPixelGeometry pixelGeometry)
tools::Long mnSrcHeight
Definition: salgtype.hxx:44
tools::Long mnSrcWidth
Definition: salgtype.hxx:43
sk_sp< SkImage > findCachedImage(const OString &key)
DeviceVendor GetVendorFromId(uint32_t id)
Returns vendor for the given vendor ID, or VendorAll if not known.
tools::Long mnDestWidth
Definition: salgtype.hxx:47
constexpr tools::Long Width() const
VCL_DLLPUBLIC bool matrixNeedsHighQuality(const SkMatrix &matrix)
VCL_DLLPUBLIC sk_sp< SkImage > createSkImage(const SkBitmap &bitmap)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
constexpr int downscaleRatioThreshold
Definition: utils.hxx:94
tools::Long mnDestHeight
Definition: salgtype.hxx:48
tools::Long maxImageCacheSize()
int i
void disableRenderMethod(RenderMethod method)
DriverBlocklist::DeviceVendor getVendor()
Definition: utils.hxx:156
BmpScaleFlag
Definition: bitmap.hxx:54
void prefillSurface(const sk_sp< SkSurface > &surface)
VCL_DLLPUBLIC void dump(const SkBitmap &bitmap, const char *file)
Reference< XOutputStream > stream
VCL_DLLPUBLIC uint32_t vendorId
def rectangle(l)
constexpr tools::Long Height() const
VCL_DLLPUBLIC sk_sp< SkSurface > createSkSurface(int width, int height, SkColorType type=kN32_SkColorType, SkAlphaType alpha=kPremul_SkAlphaType)
void removeCachedImage(sk_sp< SkImage > image)
SkSamplingOptions makeSamplingOptions(BmpScaleFlag scaling, const SkMatrix &matrix)
Definition: utils.hxx:96
ResultType type
void addCachedImage(const OString &key, sk_sp< SkImage > image)
VCL_DLLPUBLIC void prepareSkia(std::unique_ptr< sk_app::WindowContext >(*createVulkanWindowContext)(bool))