• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 2022 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "rs_base_render_util.h"
18 
19 #include <parameters.h>
20 #include <sys/stat.h>
21 #include <sys/time.h>
22 #include <unistd.h>
23 #include <unordered_set>
24 
25 #include "common/rs_matrix3.h"
26 #include "common/rs_obj_abs_geometry.h"
27 #include "common/rs_optional_trace.h"
28 #include "common/rs_vector2.h"
29 #include "common/rs_vector3.h"
30 #include "draw/clip.h"
31 #include "drawable/rs_display_render_node_drawable.h"
32 #include "effect/color_filter.h"
33 #include "effect/color_matrix.h"
34 #include "include/utils/SkCamera.h"
35 #include "params/rs_surface_render_params.h"
36 #include "pipeline/rs_surface_handler.h"
37 #include "platform/common/rs_log.h"
38 #include "png.h"
39 #include "rs_frame_rate_vote.h"
40 #include "rs_trace.h"
41 #include "rs_uni_render_thread.h"
42 #include "rs_uni_render_util.h"
43 #include "system/rs_system_parameters.h"
44 #include "transaction/rs_transaction_data.h"
45 #include "utils/camera3d.h"
46 
47 namespace OHOS {
48 namespace Rosen {
49 namespace {
50 const std::string DUMP_CACHESURFACE_DIR = "/data/cachesurface";
51 const std::string DUMP_CANVASDRAWING_DIR = "/data/canvasdrawing";
52 constexpr uint32_t API14 = 14;
53 constexpr uint32_t API18 = 18;
54 constexpr uint32_t INVALID_API_COMPATIBLE_VERSION = 0;
55 
GenerateCurrentTimeStamp()56 inline int64_t GenerateCurrentTimeStamp()
57 {
58     struct timeval now;
59     if (gettimeofday(&now, nullptr) == 0) {
60         constexpr int64_t secToUsec = 1000 * 1000;
61         return static_cast<int64_t>(now.tv_sec) * secToUsec + static_cast<int64_t>(now.tv_usec);
62     }
63     return 0;
64 }
65 }
66 namespace Detail {
67 // [PLANNING]: Use GPU to do the gamut conversion instead of these following works.
68 using PixelTransformFunc = std::function<float(float)>;
69 
70 using Offset = std::pair<uint8_t, uint8_t>; // first: offsetSrc; second: offsetDst
71 const int dstLength = 3;
72 using Array3ptr = std::array<uint8_t*, dstLength>;
73 const uint32_t STUB_PIXEL_FMT_RGBA_16161616 = 0X7fff0001;
74 const uint32_t STUB_PIXEL_FMT_RGBA_1010102 = 0X7fff0002;
75 constexpr uint32_t MATRIX_SIZE = 20; // colorMatrix size
76 constexpr int BITMAP_DEPTH = 8;
77 
PassThrough(float v)78 inline constexpr float PassThrough(float v)
79 {
80     return v;
81 }
82 
83 template<typename T>
Saturate(T v)84 static constexpr T Saturate(T v) noexcept
85 {
86     return T(std::min(static_cast<T>(1), std::max(static_cast<T>(0), v)));
87 }
88 
ApplyTransForm(const Vector3f & val,const PixelTransformFunc & func)89 inline Vector3f ApplyTransForm(const Vector3f& val, const PixelTransformFunc& func)
90 {
91     return Vector3f {func(val.x_), func(val.y_), func(val.z_)};
92 }
93 
SafePow(float x,float e)94 inline float SafePow(float x, float e)
95 {
96     return powf(x < 0.0f ? 0.0f : x, e);
97 }
98 
GenOETF(float gamma)99 inline PixelTransformFunc GenOETF(float gamma)
100 {
101     if (ROSEN_EQ(gamma, 1.0f) || ROSEN_EQ(gamma, 0.0f)) {
102         return PassThrough;
103     }
104 
105     return [gamma](float x) { return SafePow(x, 1.0f / gamma); };
106 }
107 
GenEOTF(float gamma)108 inline PixelTransformFunc GenEOTF(float gamma)
109 {
110     if (ROSEN_EQ(gamma, 1.0f)) {
111         return PassThrough;
112     }
113 
114     return [gamma](float x) { return SafePow(x, gamma); };
115 }
116 
117 struct TransferParameters {
118     float g = 0.0f;
119     float a = 0.0f;
120     float b = 0.0f;
121     float c = 0.0f;
122     float d = 0.0f;
123     float e = 0.0f;
124     float f = 0.0f;
125 };
126 
RcpResponsePq(float x,const TransferParameters & p)127 inline float RcpResponsePq(float x, const TransferParameters& p)
128 {
129     float tmp = powf(x, p.a);
130     return std::powf((p.c + p.d * tmp) / (1 + p.e * tmp), p.b);
131 }
132 
ResponsePq(float x,const TransferParameters & p)133 inline float ResponsePq(float x, const TransferParameters& p)
134 {
135     float tmp = powf(x, 1.f / p.b);
136     return std::powf(std::max((tmp - p.c), p.f) / (p.d - p.e * tmp), 1.f / p.a);
137 }
138 
139 
RcpResponse(float x,const TransferParameters & p)140 static constexpr float RcpResponse(float x, const TransferParameters& p)
141 {
142     return x >= p.d * p.c ? (std::pow(x, 1.0f / p.g) - p.b) / p.a : x / p.c;
143 }
144 
Response(float x,const TransferParameters & p)145 inline constexpr float Response(float x, const TransferParameters& p)
146 {
147     return x >= p.d ? std::pow(p.a * x + p.b, p.g) : p.c * x;
148 }
149 
RcpFullResponse(float x,const TransferParameters & p)150 inline constexpr float RcpFullResponse(float x, const TransferParameters& p)
151 {
152     return x >= p.d * p.c ? (std::pow(x - p.e, 1.0f / p.g) - p.b) / p.a : (x - p.f) / p.c;
153 }
154 
FullResponse(float x,const TransferParameters & p)155 inline constexpr float FullResponse(float x, const TransferParameters& p)
156 {
157     return x >= p.d ? std::pow(p.a * x + p.b, p.g) + p.e : p.c * x + p.f;
158 }
159 
GenOETF(const TransferParameters & params)160 inline PixelTransformFunc GenOETF(const TransferParameters& params)
161 {
162     if (params.g < 0.0f) { // HDR
163         return [params](float x) { return RcpResponsePq(x, params); };
164     }
165 
166     if (ROSEN_EQ(params.e, 0.0f) && ROSEN_EQ(params.f, 0.0f)) {
167         return [params](float x) { return RcpResponse(x, params); };
168     }
169 
170     return [params](float x) { return RcpFullResponse(x, params); };
171 }
172 
GenEOTF(const TransferParameters & params)173 inline PixelTransformFunc GenEOTF(const TransferParameters& params)
174 {
175     if (params.g < 0.0f) {
176         return [params](float x) { return ResponsePq(x, params); };
177     }
178 
179     if (ROSEN_EQ(params.e, 0.0f) && ROSEN_EQ(params.f, 0.0f)) {
180         return [params](float x) { return Response(x, params); };
181     }
182 
183     return [params](float x) { return FullResponse(x, params); };
184 }
185 
ACESToneMapping(float color,float targetLum)186 float ACESToneMapping(float color, float targetLum)
187 {
188     const float a = 2.51f;
189     const float b = 0.03f;
190     const float c = 2.43f;
191     const float d = 0.59f;
192     const float e = 0.14f;
193 
194     color *= targetLum;
195     return (color * (a * color + b)) / (color * (c * color + d) + e);
196 }
197 
GenACESToneMapping(float targetLum)198 inline PixelTransformFunc GenACESToneMapping(float targetLum)
199 {
200     if (targetLum <= 0) {
201         const float defaultLum = 200.f;
202         targetLum = defaultLum;
203     }
204     return [targetLum](float color) { return ACESToneMapping(color, targetLum); };
205 }
206 
GenRGBToXYZMatrix(const std::array<Vector2f,3> & basePoints,const Vector2f & whitePoint)207 Matrix3f GenRGBToXYZMatrix(const std::array<Vector2f, 3>& basePoints, const Vector2f& whitePoint)
208 {
209     const Vector2f& R = basePoints[0];
210     const Vector2f& G = basePoints[1];
211     const Vector2f& B = basePoints[2];
212 
213     float RxRy = R.x_ / R.y_;
214     float GxGy = G.x_ / G.y_;
215     float BxBy = B.x_ / B.y_;
216     float WxWy = whitePoint.x_ / whitePoint.y_;
217 
218     float oneRxRy = (1 - R.x_) / R.y_;
219     float oneGxGy = (1 - G.x_) / G.y_;
220     float oneBxBy = (1 - B.x_) / B.y_;
221     float oneWxWy = (1 - whitePoint.x_) / whitePoint.y_;
222 
223     float BY =
224         ((oneWxWy - oneRxRy) * (GxGy - RxRy) - (WxWy - RxRy) * (oneGxGy - oneRxRy)) /
225         ((oneBxBy - oneRxRy) * (GxGy - RxRy) - (BxBy - RxRy) * (oneGxGy - oneRxRy));
226     float GY = (WxWy - RxRy - BY * (BxBy - RxRy)) / (GxGy - RxRy);
227     float RY = 1 - GY - BY;
228 
229     float RYRy = RY / R.y_;
230     float GYGy = GY / G.y_;
231     float BYBy = BY / B.y_;
232 
233     return Matrix3f {
234         RYRy * R.x_, RY, RYRy * (1 - R.x_ - R.y_),
235         GYGy * G.x_, GY, GYGy * (1 - G.x_ - G.y_),
236         BYBy * B.x_, BY, BYBy * (1 - B.x_ - B.y_)
237     };
238 }
InvertColorMat(float hdrBrightnessRatio)239 static const std::shared_ptr<Drawing::ColorFilter> InvertColorMat(float hdrBrightnessRatio)
240 {
241     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
242         0.402,  -1.174, -0.228, 1.0, 0.0,
243         -0.598, -0.174, -0.228, 1.0, 0.0,
244         -0.599, -1.175, 0.772,  1.0, 0.0,
245         0.0,    0.0,    0.0,    1.0, 0.0
246     };
247     if (!ROSEN_EQ(hdrBrightnessRatio, 1.f)) {
248         const Drawing::scalar brightnessMatrixArray[MATRIX_SIZE] = {
249             1.0,  0.0, 0.0, hdrBrightnessRatio - 1.0, 0.0,
250             0.0,  1.0, 0.0, hdrBrightnessRatio - 1.0, 0.0,
251             0.0,  0.0, 1.0, hdrBrightnessRatio - 1.0, 0.0,
252             0.0,  0.0, 0.0, 1.0, 0.0
253         };
254         return Drawing::ColorFilter::CreateComposeColorFilter(brightnessMatrixArray, colorMatrixArray);
255     }
256     static auto invertColorMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
257     return invertColorMat;
258 }
259 
ProtanomalyMat()260 static const std::shared_ptr<Drawing::ColorFilter>& ProtanomalyMat()
261 {
262     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
263         0.622,  0.377,  0.0, 0.0, 0.0,
264         0.264,  0.736,  0.0, 0.0, 0.0,
265         0.217,  -0.217, 1.0, 0.0, 0.0,
266         0.0,    0.0,    0.0, 1.0, 0.0
267     };
268     static auto protanomalyMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
269     return protanomalyMat;
270 }
271 
DeuteranomalyMat()272 static const std::shared_ptr<Drawing::ColorFilter>& DeuteranomalyMat()
273 {
274     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
275         0.288,  0.712, 0.0, 0.0, 0.0,
276         0.053,  0.947, 0.0, 0.0, 0.0,
277         -0.258, 0.258, 1.0, 0.0, 0.0,
278         0.0,    0.0,   0.0, 1.0, 0.0
279     };
280     static auto deuteranomalyMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
281     return deuteranomalyMat;
282 }
283 
TritanomalyMat()284 static const std::shared_ptr<Drawing::ColorFilter>& TritanomalyMat()
285 {
286     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
287         1.0, -0.806, 0.806, 0.0, 0.0,
288         0.0, 0.379,  0.621, 0.0, 0.0,
289         0.0, 0.105,  0.895, 0.0, 0.0,
290         0.0, 0.0,    0.0,   1.0, 0.0
291     };
292     static auto tritanomalyMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
293     return tritanomalyMat;
294 }
295 
InvertProtanomalyMat()296 static const std::shared_ptr<Drawing::ColorFilter>& InvertProtanomalyMat()
297 {
298     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
299         -0.109, -0.663, -0.228, 1.0, 0.0,
300         -0.468, -0.304, -0.228, 1.0, 0.0,
301         -0.516, -1.258, 0.772,  1.0, 0.0,
302         0.0,    0.0,    0.0,    1.0, 0.0
303     };
304     static auto invertProtanomalyMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
305     return invertProtanomalyMat;
306 }
307 
InvertDeuteranomalyMat()308 static const std::shared_ptr<Drawing::ColorFilter>& InvertDeuteranomalyMat()
309 {
310     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
311         0.113,  -0.885, -0.228, 1.0, 0.0,
312         -0.123, -0.649, -0.228, 1.0, 0.0,
313         -0.434, -1.341, 0.772,  1.0, 0.0,
314         0.0,    0.0,    0.0,    1.0, 0.0
315     };
316     static auto invertDeuteranomalyMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
317     return invertDeuteranomalyMat;
318 }
319 
InvertTritanomalyMat()320 static const std::shared_ptr<Drawing::ColorFilter>& InvertTritanomalyMat()
321 {
322     static const Drawing::scalar colorMatrixArray[MATRIX_SIZE] = {
323         0.402,  -0.792, -0.609, 1.0, 0.0,
324         -0.598, 0.392,  -0.794, 1.0, 0.0,
325         -0.598, 0.118,  -0.521, 1.0, 0.0,
326         0.0,    0.0,    0.0,    1.0, 0.0
327     };
328     static auto invertTritanomalyMat = Drawing::ColorFilter::CreateFloatColorFilter(colorMatrixArray);
329     return invertTritanomalyMat;
330 }
331 
332 class SimpleColorSpace {
333 public:
334     // 3 RGB basePoints and 1 whitePoint.
SimpleColorSpace(const std::array<Vector2f,3> & basePoints,const Vector2f & whitePoint,float gamma=0.0f,PixelTransformFunc clamper=Saturate<float>)335     SimpleColorSpace(
336         const std::array<Vector2f, 3>& basePoints,
337         const Vector2f& whitePoint,
338         float gamma = 0.0f,
339         PixelTransformFunc clamper = Saturate<float>
340     ) noexcept
341         : rgbToXyz_(GenRGBToXYZMatrix(basePoints, whitePoint)),
342           xyzToRgb_(rgbToXyz_.Inverse()),
343           transEOTF_(GenEOTF(gamma)),
344           transOETF_(GenOETF(gamma)),
345           clamper_(std::move(clamper)),
346           transferParams_({ gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f })
347     {
348     }
349 
SimpleColorSpace(const std::array<Vector2f,3> & basePoints,const Vector2f & whitePoint,const TransferParameters & parameters,PixelTransformFunc clamper=Saturate<float>)350     SimpleColorSpace(
351         const std::array<Vector2f, 3>& basePoints,
352         const Vector2f& whitePoint,
353         const TransferParameters& parameters,
354         PixelTransformFunc clamper = Saturate<float>
355     ) noexcept
356         : rgbToXyz_(GenRGBToXYZMatrix(basePoints, whitePoint)),
357           xyzToRgb_(rgbToXyz_.Inverse()),
358           transEOTF_(GenEOTF(parameters)),
359           transOETF_(GenOETF(parameters)),
360           clamper_(std::move(clamper)),
361           transferParams_(parameters)
362     {
363     }
364 
365     ~SimpleColorSpace() noexcept = default;
366 
ToneMapping(const Vector3f & color,float targetLum=0) const367     Vector3f ToneMapping(const Vector3f& color, float targetLum = 0) const
368     {
369         PixelTransformFunc toneMappingFunc = GenACESToneMapping(targetLum);
370         return ApplyTransForm(color, toneMappingFunc);
371     }
372 
ToLinear(const Vector3f & val) const373     Vector3f ToLinear(const Vector3f& val) const
374     {
375         return ApplyTransForm(val, transEOTF_);
376     }
377 
FromLinear(const Vector3f & val) const378     Vector3f FromLinear(const Vector3f& val) const
379     {
380         return ApplyTransForm(val, transOETF_);
381     }
382 
RGBToXYZ(const Vector3f & rgb) const383     Vector3f RGBToXYZ(const Vector3f& rgb) const
384     {
385         return rgbToXyz_ * ToLinear(rgb);
386     }
387 
XYZToRGB(const Vector3f & xyz) const388     Vector3f XYZToRGB(const Vector3f& xyz) const
389     {
390         return ApplyTransForm(FromLinear(xyzToRgb_ * xyz), clamper_);
391     }
392 
393 private:
394     Matrix3f rgbToXyz_;
395     Matrix3f xyzToRgb_;
396     PixelTransformFunc transEOTF_;
397     PixelTransformFunc transOETF_;
398     PixelTransformFunc clamper_;
399     TransferParameters transferParams_;
400 };
401 
GetSRGBColorSpace()402 SimpleColorSpace &GetSRGBColorSpace()
403 {
404     static SimpleColorSpace sRGB {
405         {{Vector2f{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}}, // rgb base points.
406         {0.3127f, 0.3290f}, // white points.
407         {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f, 0.0f, 0.0f}}; // TransferParameters
408     return sRGB;
409 }
410 
GetAdobeRGBColorSpace()411 SimpleColorSpace &GetAdobeRGBColorSpace()
412 {
413     static SimpleColorSpace adobeRGB {
414         {{Vector2f{0.64f, 0.33f}, {0.21f, 0.71f}, {0.15f, 0.06f}}}, // rgb base points.
415         {0.3127f, 0.3290f}, // white points.
416         2.2f}; // gamma 2.2
417     return adobeRGB;
418 }
419 
GetDisplayP3ColorSpace()420 SimpleColorSpace &GetDisplayP3ColorSpace()
421 {
422     static SimpleColorSpace displayP3 {
423         {{Vector2f{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}}, // rgb base points.
424         {0.3127f, 0.3290f}, // white points.
425         {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.039f, 0.0f, 0.0f}}; // TransferParameters
426     return displayP3;
427 }
428 
GetDCIP3ColorSpace()429 SimpleColorSpace &GetDCIP3ColorSpace()
430 {
431     static SimpleColorSpace dciP3 {
432         {{Vector2f{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}}, // rgb base points.
433         {0.314f, 0.351f}, // white points.
434         2.6f}; // gamma 2.6
435     return dciP3;
436 }
437 
GetBT2020ColorSpace()438 SimpleColorSpace &GetBT2020ColorSpace()
439 {
440     static SimpleColorSpace bt2020 {
441         {{Vector2f{0.708f, 0.292f}, {0.17f, 0.797f}, {0.131f, 0.046f}}}, // BT.2020 rgb base points.
442         {0.3127f, 0.3290f}, // BT.2020 white points.
443         {-2.0f, 0.1593017578125, 78.84375, 0.8359375, 18.8515625, 18.6875, 0.f}}; // PQ TransferParameters
444     return bt2020;
445 }
446 
IsValidMetaData(const std::vector<GraphicHDRMetaData> & metaDatas)447 bool IsValidMetaData(const std::vector<GraphicHDRMetaData> &metaDatas)
448 {
449     uint16_t validFlag = 0;
450     for (const auto& metaData : metaDatas) {
451         validFlag ^= 1 << metaData.key;
452     }
453 
454     uint16_t bitsToCheck = 0xFF;
455     // has complete and unique primaries;
456     return (validFlag & bitsToCheck) == bitsToCheck;
457 }
458 
GetColorSpaceFromMetaData(const std::vector<GraphicHDRMetaData> & metaDatas,float targetLum=0)459 SimpleColorSpace &GetColorSpaceFromMetaData(const std::vector<GraphicHDRMetaData> &metaDatas, float targetLum = 0)
460 {
461     std::vector<GraphicHDRMetaData> metaDataSorted = metaDatas;
462     std::sort(metaDataSorted.begin(), metaDataSorted.end(),
463               [&](const GraphicHDRMetaData &a, const GraphicHDRMetaData &b)->bool {
464             return a.key < b.key;
465     });
466     static SimpleColorSpace hdrPq {
467          // rgb base points.
468         {{Vector2f{metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_RED_PRIMARY_X].value,
469                    metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_RED_PRIMARY_Y].value},
470                   {metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_GREEN_PRIMARY_X].value,
471                    metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_GREEN_PRIMARY_Y].value},
472                   {metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_BLUE_PRIMARY_X].value,
473                    metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_BLUE_PRIMARY_Y].value}}},
474         {metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_WHITE_PRIMARY_X].value,
475          metaDataSorted[GraphicHDRMetadataKey::GRAPHIC_MATAKEY_WHITE_PRIMARY_Y].value}, // white points.
476         {-2.0f, 0.1593017578125, 78.84375, 0.8359375, 18.8515625, 18.6875, 0.f}}; // PQ TransferParameters
477     return hdrPq;
478 }
479 
GetHdrPqColorSpace(const std::vector<GraphicHDRMetaData> & metaData,float targetLum=0.f)480 SimpleColorSpace &GetHdrPqColorSpace(const std::vector<GraphicHDRMetaData> &metaData, float targetLum = 0.f)
481 {
482     if (metaData.size() > 0 && IsValidMetaData(metaData)) {
483         return GetColorSpaceFromMetaData(metaData, targetLum);
484     }
485 
486     return GetBT2020ColorSpace();
487 }
488 
IsSupportedFormatForGamutConversion(int32_t pixelFormat)489 bool IsSupportedFormatForGamutConversion(int32_t pixelFormat)
490 {
491     static std::unordered_set<GraphicPixelFormat> supportedFormats = {
492         GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBX_8888,
493         GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888,
494         GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGB_888,
495         GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BGRX_8888,
496         GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BGRA_8888
497     };
498 
499     // Because GraphicPixelFormat has no enumeration for RBG_16,
500     // we use a temporary stub here for testing
501     // The final version should use a GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_XXXX
502     return pixelFormat == STUB_PIXEL_FMT_RGBA_16161616 ||
503         supportedFormats.count(static_cast<GraphicPixelFormat>(pixelFormat)) > 0;
504 }
505 
IsSupportedColorGamut(GraphicColorGamut colorGamut)506 bool IsSupportedColorGamut(GraphicColorGamut colorGamut)
507 {
508     static std::unordered_set<GraphicColorGamut> supportedColorGamuts = {
509         GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB,
510         GraphicColorGamut::GRAPHIC_COLOR_GAMUT_ADOBE_RGB,
511         GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_P3,
512         GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3,
513         GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2020,
514         GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2100_PQ
515     };
516     return supportedColorGamuts.count(colorGamut) > 0;
517 }
518 
GetColorSpaceOfCertainGamut(GraphicColorGamut colorGamut,const std::vector<GraphicHDRMetaData> & metaData={})519 SimpleColorSpace& GetColorSpaceOfCertainGamut(GraphicColorGamut colorGamut,
520                                               const std::vector<GraphicHDRMetaData> &metaData = {})
521 {
522     switch (colorGamut) {
523         case GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB: {
524             return GetSRGBColorSpace();
525         }
526         case GraphicColorGamut::GRAPHIC_COLOR_GAMUT_ADOBE_RGB: {
527             return GetAdobeRGBColorSpace();
528         }
529         case GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DISPLAY_P3:
530         case GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3: {
531             return GetDisplayP3ColorSpace(); // Currently p3 colorspace is displayP3
532         }
533         case GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2020:
534         case GraphicColorGamut::GRAPHIC_COLOR_GAMUT_BT2100_PQ: {
535             return GetHdrPqColorSpace(metaData);
536         }
537         default: {
538             return GetSRGBColorSpace();
539         }
540     }
541 }
542 
543 const uint16_t MAX_UINT10 = 1023;
RGBUint8ToFloat(uint8_t val)544 float RGBUint8ToFloat(uint8_t val)
545 {
546     return val * 1.0f / 255.0f; // 255.0f is the max value.
547 }
548 
549 // Used to transfer integers of pictures with color depth of 10 bits to float
RGBUint10ToFloat(uint16_t val)550 float RGBUint10ToFloat(uint16_t val)
551 {
552     return val * 1.0f / MAX_UINT10; // 1023.0f is the max value
553 }
554 
RGBFloatToUint8(float val)555 uint8_t RGBFloatToUint8(float val)
556 {
557     return static_cast<uint8_t>(Saturate(val) * 255 + 0.5f); // 255.0 is the max value, + 0.5f to avoid negative.
558 }
559 
560 // Used to transfer float values to integers for pictures with color depth of 10 bits
RGBFloatToUint10(float val)561 uint16_t RGBFloatToUint10(float val)
562 {
563     // 1023.0 is the max value, + 0.5f to avoid negative.
564     return static_cast<uint16_t>(Saturate(val) * MAX_UINT10 + 0.5f);
565 }
566 
RGBUintToFloat(uint8_t * dst,uint8_t * src,int32_t pixelFormat,Vector3f & srcColor,Array3ptr & colorDst)567 Offset RGBUintToFloat(uint8_t* dst, uint8_t* src, int32_t pixelFormat, Vector3f &srcColor,
568     Array3ptr &colorDst)
569 {
570     // Because PixelFormat does not have enumeration for RGBA_16 or RGBA_1010102,
571     // we use two special IF statements here to realize the transfer process.
572     // They should to be adjusted to the SWITCH process after the enumerations are added.
573     if (pixelFormat == STUB_PIXEL_FMT_RGBA_16161616) {
574         auto src16 = reinterpret_cast<const uint16_t*>(src);
575         // R: src[0], G: src[1], B: src[2]
576         srcColor = {RGBUint10ToFloat(src16[0]), RGBUint10ToFloat(src16[1]), RGBUint10ToFloat(src16[2])};
577         // R: dst + 0, G: dst + 1, B: dst + 2
578         colorDst = {dst + 0, dst + 1, dst + 2};
579         // Alpha: linear transfer src[3] to dst[3]
580         dst[3] = RGBFloatToUint8(RGBUint10ToFloat(src16[3]));
581         const uint8_t outPixelBits = 4;
582         const uint8_t inPixelBits = 8;
583         // 8 bytes per pixel and HDR pictures are always redrawn as sRGB
584         return std::make_pair(inPixelBits, outPixelBits);
585     }
586     if (pixelFormat == STUB_PIXEL_FMT_RGBA_1010102) {
587         auto src32 = reinterpret_cast<const uint32_t*>(src);
588         // R: 0-9 bits, G: 10-19 ts, B: 20-29bits
589         srcColor = {RGBUint10ToFloat((*src32) & 0x3FF), RGBUint10ToFloat(((*src32) >> 10) & 0x3FF),
590              RGBUint10ToFloat(((*src32) >> 20) & 0x3FF)};
591         // R: dst + 0, G: dst + 1, B: dst + 2
592         colorDst = {dst + 0, dst + 1, dst + 2};
593         // Alpha: copy src[3] to dst[3]
594         const uint8_t rbgBitsNum = 30;
595         const uint8_t alphaBitMask = 0x3;
596         const uint8_t alphaPos = 3;
597         dst[alphaPos] = static_cast<uint8_t>(((*src32) >> rbgBitsNum) & alphaBitMask);
598         return std::make_pair(4, 4); // 4 bytes per pixel and HDR pictures are always redrawn as sRGB
599     }
600     switch (static_cast<GraphicPixelFormat>(pixelFormat)) {
601         case GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBX_8888:
602         case GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGBA_8888: {
603             // R: src[0], G: src[1], B: src[2]
604             srcColor = {RGBUint8ToFloat(src[0]), RGBUint8ToFloat(src[1]), RGBUint8ToFloat(src[2])};
605             // R: dst + 0, G: dst + 1, B: dst + 2
606             colorDst = {dst + 0, dst + 1, dst + 2};
607             // Alpha: copy src[3] to dst[3]
608             dst[3] = src[3];
609             return std::make_pair(4, 4); // 4 bytes per pixel.
610         }
611         case GraphicPixelFormat::GRAPHIC_PIXEL_FMT_RGB_888: {
612             // R: src[0], G: src[1], B: src[2]
613             srcColor = {RGBUint8ToFloat(src[0]), RGBUint8ToFloat(src[1]), RGBUint8ToFloat(src[2])};
614             // R: dst + 0, G: dst + 1, B: dst + 2
615             colorDst = {dst + 0, dst + 1, dst + 2};
616             return std::make_pair(3, 3); // 3 bytes per pixel.
617         }
618         case GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BGRX_8888:
619         case GraphicPixelFormat::GRAPHIC_PIXEL_FMT_BGRA_8888: {
620             // R: src[2], G: src[1], B: src[0]
621             srcColor = {RGBUint8ToFloat(src[2]), RGBUint8ToFloat(src[1]), RGBUint8ToFloat(src[0])};
622             // R: dst + 2, G: dst + 1, B: dst + 0
623             colorDst = {dst + 2, dst + 1, dst + 0};
624             // Alpha: copy src[3] to dst[3]
625             dst[3] = src[3];
626             return std::make_pair(4, 4); // 4 bytes per pixel.
627         }
628         default: {
629             RS_LOGE("RGBUintToFloat: unexpected pixelFormat(%{public}d).", pixelFormat);
630             return std::make_pair(0, 0);
631         }
632     }
633 }
634 
ConvertColorGamut(uint8_t * dst,uint8_t * src,int32_t pixelFormat,SimpleColorSpace & srcColorSpace,SimpleColorSpace & dstColorSpace)635 Offset ConvertColorGamut(uint8_t* dst, uint8_t* src, int32_t pixelFormat, SimpleColorSpace& srcColorSpace,
636     SimpleColorSpace& dstColorSpace)
637 {
638     Vector3f srcColor;
639     Array3ptr colorDst; // color dst, 3 bytes (R G B).
640 
641     Offset len = RGBUintToFloat(dst, src, pixelFormat, srcColor, colorDst);
642     Vector3f outColor = dstColorSpace.XYZToRGB(srcColorSpace.RGBToXYZ(srcColor));
643     *(colorDst[0]) = RGBFloatToUint8(outColor[0]); // outColor 0 to colorDst[0]
644     *(colorDst[1]) = RGBFloatToUint8(outColor[1]); // outColor 1 to colorDst[1]
645     *(colorDst[2]) = RGBFloatToUint8(outColor[2]); // outColor 2 to colorDst[2]
646 
647     return len;
648 }
649 
ConvertBufferColorGamut(std::vector<uint8_t> & dstBuf,const sptr<OHOS::SurfaceBuffer> & srcBuf,GraphicColorGamut srcGamut,GraphicColorGamut dstGamut,const std::vector<GraphicHDRMetaData> & metaDatas)650 bool ConvertBufferColorGamut(std::vector<uint8_t>& dstBuf, const sptr<OHOS::SurfaceBuffer>& srcBuf,
651     GraphicColorGamut srcGamut, GraphicColorGamut dstGamut, const std::vector<GraphicHDRMetaData>& metaDatas)
652 {
653     RS_TRACE_NAME("ConvertBufferColorGamut");
654 
655     int32_t pixelFormat = srcBuf->GetFormat();
656     if (!IsSupportedFormatForGamutConversion(pixelFormat)) {
657         RS_LOGE("ConvertBufferColorGamut: the buffer's format is not supported.");
658         return false;
659     }
660     if (!IsSupportedColorGamut(srcGamut) || !IsSupportedColorGamut(dstGamut)) {
661         return false;
662     }
663 
664     uint32_t bufferSize = srcBuf->GetSize();
665     dstBuf.resize(bufferSize);
666 
667     auto bufferAddr = srcBuf->GetVirAddr();
668     uint8_t* srcStart = static_cast<uint8_t*>(bufferAddr);
669 
670     uint32_t offsetDst = 0, offsetSrc = 0;
671     auto& srcColorSpace = GetColorSpaceOfCertainGamut(srcGamut, metaDatas);
672     auto& dstColorSpace = GetColorSpaceOfCertainGamut(dstGamut, metaDatas);
673     while (offsetSrc < bufferSize) {
674         uint8_t* dst = &dstBuf[offsetDst];
675         uint8_t* src = srcStart + offsetSrc;
676         Offset len = ConvertColorGamut(dst, src, pixelFormat, srcColorSpace, dstColorSpace);
677         if (len.first == 0 || len.second == 0) {
678             return false;
679         }
680         offsetSrc += len.first;
681         offsetDst += len.second;
682     }
683     dstBuf.resize(offsetDst); // dstBuf size might not be as large ad srcBuf in HDR
684 
685     return true;
686 }
687 
688 // YUV to RGBA: Pixel value conversion table
689 static int Table_fv1[256] = { -180, -179, -177, -176, -174, -173, -172, -170, -169, -167, -166, -165, -163, -162,
690     -160, -159, -158, -156, -155, -153, -152, -151, -149, -148, -146, -145, -144, -142, -141, -139,
691     -138, -137,  -135, -134, -132, -131, -130, -128, -127, -125, -124, -123, -121, -120, -118,
692     -117, -115, -114, -113, -111, -110, -108, -107, -106, -104, -103, -101, -100, -99, -97, -96,
693     -94, -93, -92, -90,  -89, -87, -86, -85, -83, -82, -80, -79, -78, -76, -75, -73, -72, -71,
694     -69, -68, -66, -65, -64, -62, -61, -59, -58, -57, -55, -54, -52, -51, -50, -48, -47, -45,
695     -44, -43, -41, -40, -38, -37,  -36, -34, -33, -31, -30, -29, -27, -26, -24, -23, -22, -20,
696     -19, -17, -16, -15, -13, -12, -10, -9, -8, -6, -5, -3, -2, 0, 1, 2, 4, 5, 7, 8, 9, 11, 12,
697     14, 15, 16, 18, 19, 21, 22, 23, 25, 26, 28, 29, 30, 32, 33, 35, 36, 37, 39, 40, 42, 43, 44,
698     46, 47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 70, 71, 72, 74, 75, 77,
699     78, 79, 81, 82, 84, 85, 86, 88, 89, 91, 92, 93, 95, 96, 98, 99, 100, 102, 103, 105, 106, 107,
700     109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 124, 126, 127, 129, 130, 131, 133, 134,
701     136, 137, 138, 140, 141, 143, 144, 145, 147, 148,  150, 151, 152, 154, 155, 157, 158, 159, 161,
702     162, 164, 165, 166, 168, 169, 171, 172, 173, 175, 176, 178 };
703 static int Table_fv2[256] = { -92, -91, -91, -90, -89, -88, -88, -87, -86, -86, -85, -84, -83, -83, -82, -81,
704     -81, -80, -79, -78, -78, -77, -76, -76, -75, -74, -73, -73, -72, -71, -71, -70, -69, -68, -68, -67, -66,
705     -66, -65, -64, -63, -63, -62, -61, -61, -60, -59, -58, -58, -57, -56, -56, -55, -54, -53, -53, -52, -51,
706     -51, -50, -49, -48, -48, -47, -46, -46, -45, -44, -43, -43, -42, -41, -41, -40, -39, -38, -38, -37, -36,
707     -36, -35, -34, -33, -33, -32, -31, -31, -30, -29, -28, -28, -27, -26, -26, -25, -24, -23, -23, -22, -21,
708     -21, -20, -19, -18, -18, -17, -16, -16, -15, -14, -13, -13, -12, -11, -11, -10, -9, -8, -8, -7, -6, -6,
709     -5, -4, -3, -3, -2, -1, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 14, 15, 15, 16,
710     17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35,
711     36, 37, 37, 38, 39, 40, 40, 41, 42, 42, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50, 50, 51, 52, 52, 53, 54, 55,
712     55, 56, 57, 57, 58, 59, 60, 60, 61, 62, 62, 63, 64, 65, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72, 73, 74,
713     75, 75, 76, 77, 77, 78, 79, 80, 80, 81, 82, 82, 83, 84, 85, 85, 86, 87, 87, 88, 89, 90, 90 };
714 static int Table_fu1[256] = { -44, -44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -41, -40, -40, -40, -39, -39,
715     -39, -38, -38, -38, -37, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -33, -33, -33, -32, -32, -32, -31,
716     -31, -31, -30, -30, -30, -29, -29, -29, -28, -28, -28, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24,
717     -24, -23, -23, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16,
718     -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -11, -11, -11, -10, -10, -10, -9, -9, -9, -8,
719     -8, -8, -7, -7, -7, -6, -6, -6, -5, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, 0, 0, 0, 1, 1, 1, 2, 2,
720     2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13,
721     14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23,
722     23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32,
723     32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41,
724     41, 42, 42, 42, 43, 43 };
725 static int Table_fu2[256] = { -227, -226, -224, -222, -220, -219, -217, -215, -213, -212, -210, -208, -206, -204,
726     -203, -201, -199, -197, -196, -194, -192, -190, -188, -187, -185, -183, -181, -180, -178, -176, -174, -173,
727     -171, -169, -167, -165, -164, -162, -160, -158, -157, -155, -153, -151, -149, -148, -146, -144, -142, -141,
728     -139, -137, -135, -134, -132, -130, -128, -126, -125, -123, -121, -119, -118, -116, -114, -112, -110, -109,
729     -107, -105, -103, -102, -100, -98, -96, -94, -93, -91, -89, -87, -86, -84, -82, -80, -79, -77, -75, -73,
730     -71, -70, -68, -66, -64, -63, -61, -59, -57, -55, -54, -52, -50, -48, -47, -45, -43, -41, -40, -38, -36,
731     -34, -32, -31, -29, -27, -25, -24, -22, -20, -18, -16, -15, -13, -11, -9, -8, -6, -4, -2, 0, 1, 3, 5, 7, 8,
732     10, 12, 14, 15, 17, 19, 21, 23, 24, 26, 28, 30, 31, 33, 35, 37, 39, 40, 42, 44, 46, 47, 49, 51, 53, 54, 56,
733     58, 60, 62, 63, 65, 67, 69, 70, 72, 74, 76, 78, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 97, 99, 101, 102,
734     104, 106, 108, 109, 111, 113, 115, 117, 118, 120, 122, 124, 125, 127, 129, 131, 133, 134, 136, 138, 140, 141,
735     143, 145, 147, 148, 150, 152, 154, 156, 157, 159, 161, 163, 164, 166, 168, 170, 172, 173, 175, 177, 179, 180,
736     182, 184, 186, 187, 189, 191, 193, 195, 196, 198, 200, 202, 203, 205, 207, 209, 211, 212, 214, 216, 218,
737     219, 221, 223, 225 };
738 
ConvertYUV420SPToRGBA(std::vector<uint8_t> & rgbaBuf,const sptr<OHOS::SurfaceBuffer> & srcBuf)739 bool ConvertYUV420SPToRGBA(std::vector<uint8_t>& rgbaBuf, const sptr<OHOS::SurfaceBuffer>& srcBuf)
740 {
741     if (srcBuf == nullptr || rgbaBuf.empty()) {
742         RS_LOGE("RSBaseRenderUtil::ConvertYUV420SPToRGBA invalid params");
743         return false;
744     }
745     uint8_t* rgbaDst = &rgbaBuf[0];
746     uint8_t* src = static_cast<uint8_t*>(srcBuf->GetVirAddr());
747     if (src == nullptr || rgbaDst == nullptr) {
748         RS_LOGE("RSBaseRenderUtil::ConvertYUV420SPToRGBA null buffer ptr");
749         return false;
750     }
751     int32_t bufferWidth = srcBuf->GetWidth();
752     int32_t bufferHeight = srcBuf->GetHeight();
753     int32_t bufferStride = srcBuf->GetStride();
754     int32_t bufferSize = static_cast<int32_t>(srcBuf->GetSize());
755     if (bufferWidth < 1 || bufferHeight < 1 || bufferStride < 1 || bufferSize < 1) {
756         RS_LOGE("RSBaseRenderUtil::ConvertYUV420SPToRGBA invalid buffer size, w/h/stride/size = [%{public}d,"
757             " %{public}d, %{public}d, %{public}d]", bufferWidth, bufferHeight, bufferStride, bufferSize);
758         return false;
759     }
760 #ifdef PADDING_HEIGHT_32
761     // temporally only update buffer len for video stream
762     if (srcBuf->GetFormat() == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
763         int32_t paddingBase = 32;
764         bufferHeight = ((bufferHeight - 1) / paddingBase + 1) * paddingBase;
765     }
766 #endif
767     float yuvSizeFactor = 1.5f; // y:uv = 2:1
768     int32_t len = bufferStride * bufferHeight;
769     int32_t totalLen = static_cast<int32_t>(len * yuvSizeFactor);
770     if (bufferSize < totalLen) {
771         RS_LOGE("RSBaseRenderUtil::ConvertYUV420SPToRGBA invalid buffer size, "
772             "w/h/stride/size/totalLen = [%{public}d, %{public}d, %{public}d, %{public}d, %{public}d]",
773             bufferWidth, srcBuf->GetHeight(), bufferStride, bufferSize, totalLen);
774         return false;
775     }
776     uint8_t* ybase = src;
777     uint8_t* ubase = &src[len];
778 
779     int rgb[3] = {0, 0, 0};
780     int idx = 0;
781     int rdif = 0;
782     int invgdif = 0;
783     int bdif = 0;
784     for (int i = 0; i < bufferHeight; i++) {
785         for (int j = 0; j < bufferWidth; j++) {
786             int Y = static_cast<int>(ybase[i * bufferStride + j]);
787             int U = static_cast<int>(ubase[i / 2 * bufferStride + (j / 2) * 2 + 1]);
788             int V = static_cast<int>(ubase[i / 2 * bufferStride + (j / 2) * 2]);
789             if (srcBuf->GetFormat() == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
790                 std::swap(U, V);
791             }
792             rdif = Table_fv1[V];
793             invgdif = Table_fu1[U] + Table_fv2[V];
794             bdif = Table_fu2[U];
795 
796             rgb[0] = Y + rdif;
797             rgb[1] = Y - invgdif;
798             rgb[2] = Y + bdif; // 2 is index
799 
800             for (int k = 0; k < 3; k++) { // 3 is index
801                 idx = (i * bufferWidth + j) * 4 + k; // 4 is color channel
802                 if (rgb[k] >= 0 && rgb[k] <= 255) { // 255 is upper threshold
803                     rgbaDst[idx] = static_cast<uint8_t>(rgb[k]);
804                 } else {
805                     rgbaDst[idx] = (rgb[k] < 0) ? 0 : 255; // 255 is upper threshold
806                 }
807             }
808             ++idx;
809             rgbaDst[idx] = 255; // 255 is upper threshold
810         }
811     }
812     return true;
813 }
814 } // namespace Detail
815 
816 bool RSBaseRenderUtil::enableClient = false;
817 
SetNeedClient(bool flag)818 void RSBaseRenderUtil::SetNeedClient(bool flag)
819 {
820     enableClient = flag;
821 }
822 
IsNeedClient(RSRenderNode & node,const ComposeInfo & info)823 bool RSBaseRenderUtil::IsNeedClient(RSRenderNode& node, const ComposeInfo& info)
824 {
825     if (RSSystemProperties::IsForceClient()) {
826         RS_LOGD("RsDebug RSBaseRenderUtil::IsNeedClient: client composition is force enabled.");
827         return true;
828     }
829 
830     if (enableClient) {
831         RS_LOGD("RsDebug RSBaseRenderUtil::IsNeedClient enable composition client");
832         return true;
833     }
834 
835     const auto& property = node.GetRenderProperties();
836     auto backgroundColor = static_cast<Drawing::ColorQuad>(property.GetBackgroundColor().AsArgbInt());
837     // If node's gravity is not RESIZE and backgroundColor is not transparent,
838     // we check the src and dst size to decide whether to use client composition or not.
839     if (property.GetFrameGravity() != Gravity::RESIZE &&
840             Drawing::Color::ColorQuadGetA(backgroundColor) != Drawing::Color::COLOR_TRANSPARENT &&
841         (info.srcRect.w != info.dstRect.w || info.srcRect.h != info.dstRect.h)) {
842         return true;
843     }
844 
845     if (property.GetBackgroundFilter() || property.GetFilter()) {
846         RS_LOGD("RsDebug RSBaseRenderUtil::IsNeedClient enable composition client need filter");
847         return true;
848     }
849 
850     if (!property.GetCornerRadius().IsZero()) {
851         RS_LOGD("RsDebug RSBaseRenderUtil::IsNeedClient enable composition client need round corner");
852         return true;
853     }
854     if (property.IsShadowValid()) {
855         RS_LOGD("RsDebug RSBaseRenderUtil::IsNeedClient enable composition client need shadow");
856         return true;
857     }
858     if (node.IsInstanceOf<RSSurfaceRenderNode>() &&
859         (property.GetRotation() != 0 || property.GetRotationX() != 0 || property.GetRotationY() != 0 ||
860         property.GetQuaternion() != Quaternion())) {
861         RS_LOGD("RsDebug RSBaseRenderUtil::IsNeedClient enable composition client need RSSurfaceRenderNode rotation");
862         return true;
863     }
864     return false;
865 }
866 
GetFrameBufferRequestConfig(const ScreenInfo & screenInfo,bool isProtected,GraphicColorGamut colorGamut,GraphicPixelFormat pixelFormat)867 BufferRequestConfig RSBaseRenderUtil::GetFrameBufferRequestConfig(const ScreenInfo& screenInfo,
868     bool isProtected, GraphicColorGamut colorGamut, GraphicPixelFormat pixelFormat)
869 {
870     BufferRequestConfig config {};
871     auto width = screenInfo.isSamplingOn ? screenInfo.phyWidth : screenInfo.width;
872     auto height = screenInfo.isSamplingOn ? screenInfo.phyHeight : screenInfo.height;
873     config.width = static_cast<int32_t>(width);
874     config.height = static_cast<int32_t>(height);
875     config.strideAlignment = 0x8; // default stride is 8 Bytes.
876     config.colorGamut = colorGamut;
877     config.format = pixelFormat;
878     config.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_FB;
879     if (isProtected) {
880         config.usage |= BUFFER_USAGE_PROTECTED | BUFFER_USAGE_DRM_REDRAW; // for redraw frameBuffer mem reservation
881     }
882     config.timeout = 0;
883     return config;
884 }
885 
DropFrameProcess(RSSurfaceHandler & surfaceHandler,uint64_t presentWhen,bool adaptiveDVSyncEnable)886 GSError RSBaseRenderUtil::DropFrameProcess(RSSurfaceHandler& surfaceHandler, uint64_t presentWhen,
887     bool adaptiveDVSyncEnable)
888 {
889     auto availableBufferCnt = surfaceHandler.GetAvailableBufferCount();
890     const auto surfaceConsumer = surfaceHandler.GetConsumer();
891     if (surfaceConsumer == nullptr) {
892         RS_LOGE("RsDebug RSBaseRenderUtil::DropFrameProcess (node: %{public}" PRIu64 "): surfaceConsumer is null!",
893             surfaceHandler.GetNodeId());
894         return OHOS::GSERROR_NO_CONSUMER;
895     }
896 
897     // maxDirtyListSize should minus one buffer used for displaying, and another one that has just been acquried.
898     int32_t maxDirtyListSize = static_cast<int32_t>(surfaceConsumer->GetQueueSize()) - 1 - 1;
899     if (adaptiveDVSyncEnable) {
900         // adaptiveDVSync need more buffer
901         maxDirtyListSize++;
902     }
903     // maxDirtyListSize > 1 means QueueSize >3 too
904     if (maxDirtyListSize > 1 && availableBufferCnt >= maxDirtyListSize) {
905         RS_TRACE_NAME("DropFrame");
906         IConsumerSurface::AcquireBufferReturnValue returnValue;
907         returnValue.fence = SyncFence::InvalidFence();
908         int32_t ret = surfaceConsumer->AcquireBuffer(returnValue, static_cast<int64_t>(presentWhen), false);
909         if (ret != OHOS::SURFACE_ERROR_OK) {
910             RS_LOGW("RSBaseRenderUtil::DropFrameProcess(node: %{public}" PRIu64 "): AcquireBuffer failed("
911                 " ret: %{public}d), do nothing ", surfaceHandler.GetNodeId(), ret);
912             return OHOS::GSERROR_NO_BUFFER;
913         }
914 
915         ret = surfaceConsumer->ReleaseBuffer(returnValue.buffer, returnValue.fence);
916         if (ret != OHOS::SURFACE_ERROR_OK) {
917             RS_LOGW("RSBaseRenderUtil::DropFrameProcess(node: %{public}" PRIu64
918                     "): ReleaseBuffer failed(ret: %{public}d), Acquire done ",
919                 surfaceHandler.GetNodeId(), ret);
920         }
921         surfaceHandler.SetAvailableBufferCount(static_cast<int32_t>(surfaceConsumer->GetAvailableBufferCount()));
922         RS_LOGD("RsDebug RSBaseRenderUtil::DropFrameProcess (node: %{public}" PRIu64 "), drop one frame",
923             surfaceHandler.GetNodeId());
924     }
925 
926     return OHOS::GSERROR_OK;
927 }
928 
GetColorTypeFromBufferFormat(int32_t pixelFmt)929 Drawing::ColorType RSBaseRenderUtil::GetColorTypeFromBufferFormat(int32_t pixelFmt)
930 {
931     switch (pixelFmt) {
932         case GRAPHIC_PIXEL_FMT_RGBA_8888:
933             return Drawing::ColorType::COLORTYPE_RGBA_8888;
934         case GRAPHIC_PIXEL_FMT_RGBX_8888:
935             return Drawing::ColorType::COLORTYPE_RGB_888X;
936         case GRAPHIC_PIXEL_FMT_BGRA_8888 :
937             return Drawing::ColorType::COLORTYPE_BGRA_8888;
938         case GRAPHIC_PIXEL_FMT_RGB_565:
939             return Drawing::ColorType::COLORTYPE_RGB_565;
940         case GRAPHIC_PIXEL_FMT_YCBCR_P010:
941         case GRAPHIC_PIXEL_FMT_YCRCB_P010:
942         case GRAPHIC_PIXEL_FMT_RGBA_1010102:
943             return Drawing::ColorType::COLORTYPE_RGBA_1010102;
944         default:
945             return Drawing::ColorType::COLORTYPE_RGBA_8888;
946     }
947 }
948 
MergeBufferDamages(const std::vector<Rect> & damages)949 Rect RSBaseRenderUtil::MergeBufferDamages(const std::vector<Rect>& damages)
950 {
951     RectI damage;
952     std::for_each(damages.begin(), damages.end(), [&damage](const Rect& damageRect) {
953         damage = damage.JoinRect(RectI(damageRect.x, damageRect.y, damageRect.w, damageRect.h));
954     });
955     return {damage.left_, damage.top_, damage.width_, damage.height_};
956 }
957 
ConsumeAndUpdateBuffer(RSSurfaceHandler & surfaceHandler,uint64_t presentWhen,bool dropFrameByPidEnable,bool adaptiveDVSyncEnable,bool needConsume)958 bool RSBaseRenderUtil::ConsumeAndUpdateBuffer(RSSurfaceHandler& surfaceHandler,
959     uint64_t presentWhen, bool dropFrameByPidEnable, bool adaptiveDVSyncEnable, bool needConsume)
960 {
961     if (surfaceHandler.GetAvailableBufferCount() <= 0) {
962         return true;
963     }
964     const auto& consumer = surfaceHandler.GetConsumer();
965     if (consumer == nullptr) {
966         RS_LOGE("Consume and update buffer fail for consumer is nullptr");
967         return false;
968     }
969     if (adaptiveDVSyncEnable && !needConsume) {
970         RS_LOGI("adaptiveDVSyncEnable and not needConsume");
971         return false;
972     }
973 
974     // check presentWhen conversion validation range
975     bool presentWhenValid = presentWhen <= static_cast<uint64_t>(INT64_MAX);
976     bool acqiureWithPTSEnable =
977         RSUniRenderJudgement::IsUniRender() && RSSystemParameters::GetControlBufferConsumeEnabled() &&
978             !adaptiveDVSyncEnable;
979     uint64_t acquireTimeStamp = presentWhen;
980     if (!presentWhenValid || !acqiureWithPTSEnable) {
981         acquireTimeStamp = CONSUME_DIRECTLY;
982         RS_LOGD("RSBaseRenderUtil::ConsumeAndUpdateBuffer ignore presentWhen "\
983             "[acqiureWithPTSEnable:%{public}d, presentWhenValid:%{public}d]", acqiureWithPTSEnable, presentWhenValid);
984     }
985 
986     std::shared_ptr<RSSurfaceHandler::SurfaceBufferEntry> surfaceBuffer;
987     if (surfaceHandler.GetHoldBuffer() == nullptr) {
988         IConsumerSurface::AcquireBufferReturnValue returnValue;
989         int32_t ret;
990         if (acqiureWithPTSEnable && dropFrameByPidEnable) {
991             ret = consumer->AcquireBuffer(returnValue, INT64_MAX, true);
992         } else {
993             ret = consumer->AcquireBuffer(returnValue, static_cast<int64_t>(acquireTimeStamp), false);
994         }
995         if (returnValue.buffer == nullptr || ret != SURFACE_ERROR_OK) {
996             RS_LOGE("RsDebug surfaceHandler(id: %{public}" PRIu64 ") AcquireBuffer failed(ret: %{public}d)!",
997                 surfaceHandler.GetNodeId(), ret);
998             surfaceBuffer = nullptr;
999             return false;
1000         }
1001         surfaceBuffer = std::make_shared<RSSurfaceHandler::SurfaceBufferEntry>();
1002         surfaceBuffer->buffer = returnValue.buffer;
1003         surfaceBuffer->acquireFence = returnValue.fence;
1004         surfaceBuffer->timestamp = returnValue.timestamp;
1005         RS_LOGD_IF(DEBUG_PIPELINE,
1006             "RsDebug surfaceHandler(id: %{public}" PRIu64 ") AcquireBuffer success, acquireTimeStamp = "
1007             "%{public}" PRIu64 ", buffer timestamp = %{public}" PRId64 ", seq = %{public}" PRIu32 ".",
1008             surfaceHandler.GetNodeId(), acquireTimeStamp, surfaceBuffer->timestamp, surfaceBuffer->buffer->GetSeqNum());
1009         RS_TRACE_NAME_FMT("RsDebug surfaceHandler(id: %" PRIu64 ") AcquireBuffer success, acquireTimeStamp = "
1010             "%" PRIu64 ", buffer timestamp = %" PRId64 ", seq = %" PRIu32 ".",
1011             surfaceHandler.GetNodeId(), acquireTimeStamp, surfaceBuffer->timestamp,
1012             surfaceBuffer->buffer->GetSeqNum());
1013         // The damages of buffer will be merged here, only single damage is supported so far
1014         Rect damageAfterMerge = MergeBufferDamages(returnValue.damages);
1015         if (damageAfterMerge.h <= 0 || damageAfterMerge.w <= 0) {
1016             RS_LOGW("RsDebug surfaceHandler(id: %{public}" PRIu64 ") buffer damage is invalid",
1017                 surfaceHandler.GetNodeId());
1018         }
1019         // Flip damage because the rect is specified relative to the bottom-left of the surface in gl,
1020         // but the damages is specified relative to the top-left in rs.
1021         // The damages in vk is also transformed to the same as gl now.
1022         // [planning]: Unify the damage's coordinate systems of vk and gl.
1023         damageAfterMerge.y = surfaceBuffer->buffer->GetHeight() - damageAfterMerge.y - damageAfterMerge.h;
1024         surfaceBuffer->damageRect = damageAfterMerge;
1025         if (consumer->IsBufferHold()) {
1026             surfaceHandler.SetHoldBuffer(surfaceBuffer);
1027             surfaceBuffer = nullptr;
1028             RS_LOGW("RsDebug surfaceHandler(id: %{public}" PRIu64 ") set hold buffer",
1029                 surfaceHandler.GetNodeId());
1030             return true;
1031         }
1032     }
1033     if (consumer->IsBufferHold()) {
1034         surfaceBuffer = surfaceHandler.GetHoldBuffer();
1035         surfaceHandler.SetHoldBuffer(nullptr);
1036         consumer->SetBufferHold(false);
1037         RS_LOGW("RsDebug surfaceHandler(id: %{public}" PRIu64 ") consume hold buffer", surfaceHandler.GetNodeId());
1038     }
1039     if (surfaceBuffer == nullptr || surfaceBuffer->buffer == nullptr) {
1040         RS_LOGE("RsDebug surfaceHandler(id: %{public}" PRIu64 ") no buffer to consume", surfaceHandler.GetNodeId());
1041         return false;
1042     }
1043     surfaceHandler.ConsumeAndUpdateBuffer(*surfaceBuffer);
1044     DelayedSingleton<RSFrameRateVote>::GetInstance()->VideoFrameRateVote(surfaceHandler.GetNodeId(),
1045         consumer->GetSurfaceSourceType(), surfaceBuffer->buffer);
1046     surfaceBuffer = nullptr;
1047     surfaceHandler.SetAvailableBufferCount(static_cast<int32_t>(consumer->GetAvailableBufferCount()));
1048     // should drop frame after acquire buffer to avoid drop key frame
1049     DropFrameProcess(surfaceHandler, acquireTimeStamp, adaptiveDVSyncEnable);
1050 #ifdef RS_ENABLE_GPU
1051     auto renderEngine = RSUniRenderThread::Instance().GetRenderEngine();
1052     if (!renderEngine) {
1053         return true;
1054     }
1055     renderEngine->RegisterDeleteBufferListener(surfaceHandler);
1056     return true;
1057 #else
1058     return true;
1059 #endif
1060 }
1061 
ReleaseBuffer(RSSurfaceHandler & surfaceHandler)1062 bool RSBaseRenderUtil::ReleaseBuffer(RSSurfaceHandler& surfaceHandler)
1063 {
1064     auto consumer = surfaceHandler.GetConsumer();
1065     if (consumer == nullptr) {
1066         return false;
1067     }
1068 
1069     auto preBuffer = surfaceHandler.GetPreBuffer();
1070     if (preBuffer != nullptr) {
1071         auto ret = consumer->ReleaseBuffer(preBuffer, surfaceHandler.GetPreBufferReleaseFence());
1072         if (ret != OHOS::SURFACE_ERROR_OK) {
1073             RS_LOGD("RsDebug surfaceHandler(id: %{public}" PRIu64 ") ReleaseBuffer failed(ret: %{public}d)!",
1074                 surfaceHandler.GetNodeId(), ret);
1075             return false;
1076         }
1077         // reset prevBuffer if we release it successfully,
1078         // to avoid releasing the same buffer next frame in some situations.
1079         surfaceHandler.ResetPreBuffer();
1080     }
1081 
1082     return true;
1083 }
1084 
IsColorFilterModeValid(ColorFilterMode mode)1085 bool RSBaseRenderUtil::IsColorFilterModeValid(ColorFilterMode mode)
1086 {
1087     bool valid = false;
1088     switch (mode) {
1089         case ColorFilterMode::INVERT_COLOR_DISABLE_MODE:
1090         case ColorFilterMode::INVERT_COLOR_ENABLE_MODE:
1091         case ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE:
1092         case ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE:
1093         case ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE:
1094         case ColorFilterMode::INVERT_DALTONIZATION_PROTANOMALY_MODE:
1095         case ColorFilterMode::INVERT_DALTONIZATION_DEUTERANOMALY_MODE:
1096         case ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE:
1097         case ColorFilterMode::DALTONIZATION_NORMAL_MODE:
1098         case ColorFilterMode::COLOR_FILTER_END:
1099             valid = true;
1100             break;
1101         default:
1102             valid = false;
1103     }
1104     return valid;
1105 }
1106 
SetColorFilterModeToPaint(ColorFilterMode colorFilterMode,Drawing::Brush & paint,float hdrBrightnessRatio)1107 void RSBaseRenderUtil::SetColorFilterModeToPaint(ColorFilterMode colorFilterMode,
1108     Drawing::Brush& paint, float hdrBrightnessRatio)
1109 {
1110     Drawing::Filter filter;
1111     switch (colorFilterMode) {
1112         case ColorFilterMode::INVERT_COLOR_ENABLE_MODE:
1113             filter.SetColorFilter(Detail::InvertColorMat(hdrBrightnessRatio));
1114             break;
1115         case ColorFilterMode::DALTONIZATION_PROTANOMALY_MODE:
1116             filter.SetColorFilter(Detail::ProtanomalyMat());
1117             break;
1118         case ColorFilterMode::DALTONIZATION_DEUTERANOMALY_MODE:
1119             filter.SetColorFilter(Detail::DeuteranomalyMat());
1120             break;
1121         case ColorFilterMode::DALTONIZATION_TRITANOMALY_MODE:
1122             filter.SetColorFilter(Detail::TritanomalyMat());
1123             break;
1124         case ColorFilterMode::INVERT_DALTONIZATION_PROTANOMALY_MODE:
1125             filter.SetColorFilter(Detail::InvertProtanomalyMat());
1126             break;
1127         case ColorFilterMode::INVERT_DALTONIZATION_DEUTERANOMALY_MODE:
1128             filter.SetColorFilter(Detail::InvertDeuteranomalyMat());
1129             break;
1130         case ColorFilterMode::INVERT_DALTONIZATION_TRITANOMALY_MODE:
1131             filter.SetColorFilter(Detail::InvertTritanomalyMat());
1132             break;
1133         // INVERT_COLOR_DISABLE_MODE and DALTONIZATION_NORMAL_MODE couldn't be in this process
1134         case ColorFilterMode::INVERT_COLOR_DISABLE_MODE:
1135         case ColorFilterMode::DALTONIZATION_NORMAL_MODE:
1136         case ColorFilterMode::COLOR_FILTER_END:
1137         default:
1138             filter.SetColorFilter(nullptr);
1139             break;
1140     }
1141     paint.SetFilter(filter);
1142 }
1143 
IsBufferValid(const sptr<SurfaceBuffer> & buffer)1144 bool RSBaseRenderUtil::IsBufferValid(const sptr<SurfaceBuffer>& buffer)
1145 {
1146     if (!buffer) {
1147         RS_LOGE("RSBaseRenderUtil: buffer is nullptr");
1148         return false;
1149     }
1150     auto addr = buffer->GetVirAddr();
1151     // DRM buffers addr is nullptr
1152     if (addr == nullptr && !(buffer->GetUsage() & BUFFER_USAGE_PROTECTED)) {
1153         RS_LOGE("RSBaseRenderUtil: buffer has no vir addr");
1154         return false;
1155     }
1156     if (buffer->GetWidth() <= 0 || buffer->GetHeight() <= 0) {
1157         RS_LOGE("RSBaseRenderUtil: this buffer has negative width or height [%{public}d %{public}d]",
1158             buffer->GetWidth(), buffer->GetHeight());
1159         return false;
1160     }
1161     return true;
1162 }
1163 
GetSurfaceBufferTransformType(const sptr<IConsumerSurface> & consumer,const sptr<SurfaceBuffer> & buffer)1164 GraphicTransformType RSBaseRenderUtil::GetSurfaceBufferTransformType(
1165     const sptr<IConsumerSurface>& consumer, const sptr<SurfaceBuffer>& buffer)
1166 {
1167     auto transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
1168     if (consumer == nullptr || buffer == nullptr) {
1169         return transformType;
1170     }
1171     if (consumer->GetSurfaceBufferTransformType(buffer, &transformType) != GSERROR_OK) {
1172         RS_LOGE("RSBaseRenderUtil::GetSurfaceBufferTransformType GetSurfaceBufferTransformType failed");
1173     }
1174     return transformType;
1175 }
1176 
GetSurfaceTransformMatrix(GraphicTransformType rotationTransform,const RectF & bounds,const RectF & bufferBounds)1177 Drawing::Matrix RSBaseRenderUtil::GetSurfaceTransformMatrix(
1178     GraphicTransformType rotationTransform, const RectF &bounds, const RectF &bufferBounds)
1179 {
1180     Drawing::Matrix matrix;
1181     const float bufferWidth = bufferBounds.GetWidth();
1182     const float bufferHeight = bufferBounds.GetHeight();
1183 
1184     switch (rotationTransform) {
1185         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1186             matrix.PreTranslate(0, bufferHeight);
1187             matrix.PreRotate(-90);  // rotate 90 degrees anti-clockwise at last.
1188             break;
1189         }
1190         case GraphicTransformType::GRAPHIC_ROTATE_180: {
1191             matrix.PreTranslate(bufferWidth, bufferHeight);
1192             matrix.PreRotate(-180);  // rotate 180 degrees anti-clockwise at last.
1193             break;
1194         }
1195         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1196             matrix.PreTranslate(bufferWidth, 0);
1197             matrix.PreRotate(-270); // rotate 270 degrees anti-clockwise at last.
1198             break;
1199         }
1200         default:
1201             break;
1202     }
1203 
1204     return matrix;
1205 }
1206 
GetSurfaceTransformMatrixForRotationFixed(GraphicTransformType rotationTransform,const RectF & bounds,const RectF & bufferBounds,Gravity gravity)1207 Drawing::Matrix RSBaseRenderUtil::GetSurfaceTransformMatrixForRotationFixed(
1208     GraphicTransformType rotationTransform, const RectF &bounds, const RectF &bufferBounds, Gravity gravity)
1209 {
1210     Drawing::Matrix matrix;
1211     const float boundsWidth = bounds.GetWidth();
1212     const float boundsHeight = bounds.GetHeight();
1213     const float bufferHeight = bufferBounds.GetHeight();
1214     float heightAdjust = boundsHeight;
1215 
1216     static std::unordered_set<Gravity> resizeGravities = {Gravity::RESIZE,
1217         Gravity::RESIZE_ASPECT,
1218         Gravity::RESIZE_ASPECT_TOP_LEFT,
1219         Gravity::RESIZE_ASPECT_BOTTOM_RIGHT,
1220         Gravity::RESIZE_ASPECT_FILL,
1221         Gravity::RESIZE_ASPECT_FILL_TOP_LEFT,
1222         Gravity::RESIZE_ASPECT_FILL_BOTTOM_RIGHT};
1223     if (resizeGravities.find(gravity) != resizeGravities.end()) {
1224         heightAdjust = boundsHeight;
1225     } else if (bufferHeight > 0) {
1226         heightAdjust = std::min(bufferHeight, boundsHeight);
1227     }
1228 
1229     switch (rotationTransform) {
1230         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1231             matrix.PreTranslate(0, heightAdjust);
1232             matrix.PreRotate(-90);  // rotate 90 degrees anti-clockwise at last.
1233             break;
1234         }
1235         case GraphicTransformType::GRAPHIC_ROTATE_180: {
1236             matrix.PreTranslate(boundsWidth, heightAdjust);
1237             matrix.PreRotate(-180);  // rotate 180 degrees anti-clockwise at last.
1238             break;
1239         }
1240         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1241             matrix.PreTranslate(boundsWidth, 0);
1242             matrix.PreRotate(-270); // rotate 270 degrees anti-clockwise at last.
1243             break;
1244         }
1245         default:
1246             break;
1247     }
1248 
1249     return matrix;
1250 }
1251 
GetGravityMatrix(Gravity gravity,const RectF & bufferSize,const RectF & bounds)1252 Drawing::Matrix RSBaseRenderUtil::GetGravityMatrix(
1253     Gravity gravity, const RectF& bufferSize, const RectF& bounds)
1254 {
1255     Drawing::Matrix gravityMatrix;
1256 
1257     auto frameWidth = bufferSize.GetWidth();
1258     auto frameHeight = bufferSize.GetHeight();
1259     const float boundsWidth = bounds.GetWidth();
1260     const float boundsHeight = bounds.GetHeight();
1261     if (ROSEN_EQ(frameWidth, boundsWidth) && ROSEN_EQ(frameHeight, boundsHeight)) {
1262         return gravityMatrix;
1263     }
1264 
1265     if (!RSPropertiesPainter::GetGravityMatrix(gravity,
1266         RectF {0.0f, 0.0f, boundsWidth, boundsHeight}, frameWidth, frameHeight, gravityMatrix)) {
1267         RS_LOGD("RSBaseRenderUtil::DealWithNodeGravity did not obtain gravity matrix.");
1268     }
1269 
1270     return gravityMatrix;
1271 }
1272 
GetScreenIdFromSurfaceRenderParams(RSSurfaceRenderParams * nodeParams)1273 ScreenId RSBaseRenderUtil::GetScreenIdFromSurfaceRenderParams(RSSurfaceRenderParams* nodeParams)
1274 {
1275     ScreenId screenId = 0;
1276     if (gettid() == RSUniRenderThread::Instance().GetTid()) { // Check whether the thread is in the UniRenderThread.
1277         auto ancestorDrawable = nodeParams->GetAncestorDisplayDrawable().lock();
1278         if (ancestorDrawable == nullptr) {
1279             return screenId;
1280         }
1281         auto ancestorDisplayDrawable =
1282             std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(ancestorDrawable);
1283         if (ancestorDisplayDrawable == nullptr) {
1284             return screenId;
1285         }
1286         auto& ancestorParam = ancestorDisplayDrawable->GetRenderParams();
1287         if (ancestorParam == nullptr) {
1288             return screenId;
1289         }
1290         auto renderParams = static_cast<RSDisplayRenderParams*>(ancestorParam.get());
1291         if (renderParams == nullptr) {
1292             return screenId;
1293         }
1294         screenId = renderParams->GetScreenId();
1295     } else {
1296         std::shared_ptr<RSDisplayRenderNode> ancestor = nullptr;
1297         auto displayLock = nodeParams->GetAncestorDisplayNode().lock();
1298         if (displayLock != nullptr) {
1299             ancestor = displayLock->ReinterpretCastTo<RSDisplayRenderNode>();
1300         }
1301         if (ancestor == nullptr) {
1302             return screenId;
1303         }
1304         screenId = ancestor->GetScreenId();
1305     }
1306     return screenId;
1307 }
1308 
GetScreenRotationOffset(RSSurfaceRenderParams * nodeParams)1309 int32_t RSBaseRenderUtil::GetScreenRotationOffset(RSSurfaceRenderParams* nodeParams)
1310 {
1311     int32_t rotationDegree = 0;
1312     if (nodeParams == nullptr) {
1313         return rotationDegree;
1314     }
1315 
1316     bool isCameraRotationCompensation = RSSystemParameters::GetMultimediaEnableCameraRotationCompensation();
1317     uint32_t apiCompatibleVersion = nodeParams->GetApiCompatibleVersion();
1318     if (isCameraRotationCompensation && apiCompatibleVersion != INVALID_API_COMPATIBLE_VERSION &&
1319         apiCompatibleVersion < API14) {
1320         if (RSSystemParameters::GetWindowScreenScanType() == 1) {
1321             rotationDegree = RS_ROTATION_90;
1322         }
1323         return rotationDegree;
1324     }
1325 
1326     ScreenId screenId = GetScreenIdFromSurfaceRenderParams(nodeParams);
1327     auto screenManager = CreateOrGetScreenManager();
1328     if (screenManager) {
1329         rotationDegree =
1330             static_cast<int32_t>(RSBaseRenderUtil::RotateEnumToInt(screenManager->GetScreenCorrection(screenId)));
1331     } else {
1332         RS_LOGE("RSBaseRenderUtil::GetScreenRotationOffset: screenManager is nullptr");
1333     }
1334     RS_LOGD("RSBaseRenderUtil::GetScreenRotationOffset: ScreenId: %{public}" PRIu64 ", RotationOffset: %{public}d",
1335         screenId, rotationDegree);
1336     return rotationDegree;
1337 }
1338 
1339 #ifdef RS_ENABLE_GPU
DealWithSurfaceRotationAndGravity(GraphicTransformType transform,Gravity gravity,RectF & localBounds,BufferDrawParam & params,RSSurfaceRenderParams * nodeParams)1340 void RSBaseRenderUtil::DealWithSurfaceRotationAndGravity(GraphicTransformType transform, Gravity gravity,
1341     RectF &localBounds, BufferDrawParam &params, RSSurfaceRenderParams *nodeParams)
1342 {
1343     // the surface can rotate itself.
1344     auto rotationTransform = GetRotateTransform(transform);
1345     int extraRotation = 0;
1346     if (nodeParams != nullptr && nodeParams->GetFixRotationByUser()) {
1347         int32_t rotationDegree = GetScreenRotationOffset(nodeParams);
1348         int degree = static_cast<int>(round(nodeParams->GetAbsRotation()));
1349         extraRotation = (degree - rotationDegree) % ROUND_ANGLE;
1350         RS_OPTIONAL_TRACE_NAME_FMT("RSBaseRenderUtil::DealWithSurfaceRotationAndGravity "
1351                                    "fixRotationByUser:true surfaceNode:[%lu] rotationDegree:[%d] "
1352                                    "degree:[%d] extraRotation:[%d]", nodeParams->GetId(),
1353                                    rotationDegree, degree, extraRotation);
1354     }
1355 
1356     rotationTransform = static_cast<GraphicTransformType>(
1357         (rotationTransform + extraRotation / RS_ROTATION_90 + SCREEN_ROTATION_NUM) % SCREEN_ROTATION_NUM);
1358     RS_OPTIONAL_TRACE_NAME_FMT("RSBaseRenderUtil::DealWithSurfaceRotationAndGravity "
1359                                "surfaceNode:[%lu] transform:[%d] rotationTransform:[%d]",
1360                                nodeParams != nullptr ? nodeParams->GetId() : 0, transform, rotationTransform);
1361 
1362     RectF bufferBounds = {0.0f, 0.0f, 0.0f, 0.0f};
1363     if (params.buffer != nullptr) {
1364         bufferBounds = {0.0f, 0.0f, params.buffer->GetSurfaceBufferWidth(), params.buffer->GetSurfaceBufferHeight()};
1365         if (rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1366             rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_270) {
1367             std::swap(bufferBounds.width_, bufferBounds.height_);
1368         }
1369     }
1370 
1371     if (nodeParams != nullptr && nodeParams->GetApiCompatibleVersion() >= API18) {
1372         // deal with buffer's gravity effect in node's inner space.
1373         params.matrix.PreConcat(RSBaseRenderUtil::GetGravityMatrix(gravity, bufferBounds, localBounds));
1374         params.matrix.PreConcat(
1375             RSBaseRenderUtil::GetSurfaceTransformMatrix(rotationTransform, localBounds, bufferBounds));
1376         if (rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1377             rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_270) {
1378             // after rotate, we should swap dstRect and bound's width and height.
1379             std::swap(localBounds.width_, localBounds.height_);
1380         }
1381     } else {
1382         params.matrix.PreConcat(RSBaseRenderUtil::GetSurfaceTransformMatrixForRotationFixed(rotationTransform,
1383             localBounds, bufferBounds, gravity));
1384         if (rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_90 ||
1385             rotationTransform == GraphicTransformType::GRAPHIC_ROTATE_270) {
1386             // after rotate, we should swap dstRect and bound's width and height.
1387             std::swap(localBounds.width_, localBounds.height_);
1388             params.dstRect = Drawing::Rect(0, 0, localBounds.GetWidth(), localBounds.GetHeight());
1389             std::swap(bufferBounds.width_, bufferBounds.height_);
1390         }
1391         // deal with buffer's gravity effect in node's inner space.
1392         params.matrix.PreConcat(RSBaseRenderUtil::GetGravityMatrix(gravity, bufferBounds, localBounds));
1393     }
1394 
1395     // because we use the gravity matrix above(which will implicitly includes scale effect),
1396     // we must disable the scale effect that from srcRect to dstRect.
1397     if (UNLIKELY(params.hasCropMetadata)) {
1398         params.dstRect = Drawing::Rect(0, 0,
1399             params.buffer->GetSurfaceBufferWidth(), params.buffer->GetSurfaceBufferHeight());
1400     } else {
1401         params.dstRect = params.srcRect;
1402     }
1403 }
1404 #endif
FlipMatrix(GraphicTransformType transform,BufferDrawParam & params)1405 void RSBaseRenderUtil::FlipMatrix(GraphicTransformType transform, BufferDrawParam& params)
1406 {
1407     GraphicTransformType type = GetFlipTransform(transform);
1408     if (type != GraphicTransformType::GRAPHIC_FLIP_H && type != GraphicTransformType::GRAPHIC_FLIP_V) {
1409         return;
1410     }
1411 
1412     const int angle = 180;
1413     Drawing::Camera3D camera3D;
1414     switch (type) {
1415         case GraphicTransformType::GRAPHIC_FLIP_H: {
1416             camera3D.RotateYDegrees(angle);
1417             break;
1418         }
1419         case GraphicTransformType::GRAPHIC_FLIP_V: {
1420             camera3D.RotateXDegrees(angle);
1421             break;
1422         }
1423         default: {
1424             return;
1425         }
1426     }
1427     RS_LOGD("RSBaseRenderUtil::FlipMatrix %{public}d", transform);
1428     Drawing::Matrix flip;
1429     camera3D.ApplyToMatrix(flip);
1430     const float half = 0.5f;
1431     flip.PreTranslate(-half * params.dstRect.GetWidth(), -half * params.dstRect.GetHeight());
1432     flip.PostTranslate(half * params.dstRect.GetWidth(), half * params.dstRect.GetHeight());
1433     params.matrix.PreConcat(flip);
1434 }
1435 
SetPropertiesForCanvas(RSPaintFilterCanvas & canvas,const BufferDrawParam & params)1436 void RSBaseRenderUtil::SetPropertiesForCanvas(RSPaintFilterCanvas& canvas, const BufferDrawParam& params)
1437 {
1438     if (params.isNeedClip) {
1439         if (!params.cornerRadius.IsZero()) {
1440             canvas.ClipRoundRect(
1441                 RSPropertiesPainter::RRect2DrawingRRect(params.clipRRect), Drawing::ClipOp::INTERSECT, true);
1442         } else {
1443             canvas.ClipRect(params.clipRect, Drawing::ClipOp::INTERSECT, false);
1444         }
1445     }
1446     if (Drawing::Color::ColorQuadGetA(params.backgroundColor) != Drawing::Color::COLOR_TRANSPARENT) {
1447         canvas.DrawColor(params.backgroundColor);
1448     }
1449     canvas.ConcatMatrix(params.matrix);
1450 }
1451 
ConvertBufferToBitmap(sptr<SurfaceBuffer> buffer,std::vector<uint8_t> & newBuffer,GraphicColorGamut dstGamut,Drawing::Bitmap & bitmap,const std::vector<GraphicHDRMetaData> & metaDatas)1452 bool RSBaseRenderUtil::ConvertBufferToBitmap(sptr<SurfaceBuffer> buffer, std::vector<uint8_t>& newBuffer,
1453     GraphicColorGamut dstGamut, Drawing::Bitmap& bitmap, const std::vector<GraphicHDRMetaData>& metaDatas)
1454 {
1455     if (!IsBufferValid(buffer)) {
1456         return false;
1457     }
1458     bool bitmapCreated = false;
1459     GraphicColorGamut srcGamut = static_cast<GraphicColorGamut>(buffer->GetSurfaceBufferColorGamut());
1460     // [PLANNING]: We will not use this tmp newBuffer if we use GPU to do the color conversions.
1461     // Attention: make sure newBuffer's lifecycle is longer than the moment call drawBitmap
1462     if (buffer->GetFormat() == GRAPHIC_PIXEL_FMT_YCRCB_420_SP ||
1463         buffer->GetFormat() == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
1464         bitmapCreated = CreateYuvToRGBABitMap(buffer, newBuffer, bitmap);
1465     } else if (buffer->GetFormat() == Detail::STUB_PIXEL_FMT_RGBA_16161616) {
1466         bitmapCreated = CreateNewColorGamutBitmap(buffer, newBuffer, bitmap, srcGamut, dstGamut, metaDatas);
1467     } else if (srcGamut != dstGamut) {
1468         RS_LOGD("RSBaseRenderUtil::ConvertBufferToBitmap: need to convert color gamut.");
1469         bitmapCreated = CreateNewColorGamutBitmap(buffer, newBuffer, bitmap, srcGamut, dstGamut);
1470     } else {
1471         bitmapCreated = CreateBitmap(buffer, bitmap);
1472     }
1473     return bitmapCreated;
1474 }
1475 
CreateYuvToRGBABitMap(sptr<OHOS::SurfaceBuffer> buffer,std::vector<uint8_t> & newBuffer,Drawing::Bitmap & bitmap)1476 bool RSBaseRenderUtil::CreateYuvToRGBABitMap(sptr<OHOS::SurfaceBuffer> buffer, std::vector<uint8_t>& newBuffer,
1477     Drawing::Bitmap& bitmap)
1478 {
1479     newBuffer.resize(buffer->GetWidth() * buffer->GetHeight() * 4, 0); // 4 is color channel
1480     if (!Detail::ConvertYUV420SPToRGBA(newBuffer, buffer)) {
1481         return false;
1482     }
1483 
1484     Drawing::ImageInfo imageInfo(buffer->GetWidth(), buffer->GetHeight(),
1485         Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL);
1486     bitmap.InstallPixels(imageInfo, newBuffer.data(), buffer->GetWidth() * 4);
1487     return true;
1488 }
1489 
CreateBitmap(sptr<OHOS::SurfaceBuffer> buffer,Drawing::Bitmap & bitmap)1490 bool RSBaseRenderUtil::CreateBitmap(sptr<OHOS::SurfaceBuffer> buffer, Drawing::Bitmap& bitmap)
1491 {
1492     Drawing::BitmapFormat format = GenerateDrawingBitmapFormat(buffer);
1493     bitmap.Build(buffer->GetWidth(), buffer->GetHeight(), format, buffer->GetStride());
1494     bitmap.SetPixels(buffer->GetVirAddr());
1495     return true;
1496 }
1497 
GenerateDrawingBitmapFormat(const sptr<OHOS::SurfaceBuffer> & buffer)1498 Drawing::BitmapFormat RSBaseRenderUtil::GenerateDrawingBitmapFormat(const sptr<OHOS::SurfaceBuffer>& buffer)
1499 {
1500     Drawing::BitmapFormat format;
1501     if (buffer == nullptr) {
1502         return format;
1503     }
1504     Drawing::ColorType colorType = GetColorTypeFromBufferFormat(buffer->GetFormat());
1505     Drawing::AlphaType alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL;
1506     format = { colorType, alphaType };
1507     return format;
1508 }
1509 
CreateNewColorGamutBitmap(sptr<OHOS::SurfaceBuffer> buffer,std::vector<uint8_t> & newBuffer,Drawing::Bitmap & bitmap,GraphicColorGamut srcGamut,GraphicColorGamut dstGamut,const std::vector<GraphicHDRMetaData> & metaDatas)1510 bool RSBaseRenderUtil::CreateNewColorGamutBitmap(sptr<OHOS::SurfaceBuffer> buffer, std::vector<uint8_t>& newBuffer,
1511     Drawing::Bitmap& bitmap, GraphicColorGamut srcGamut, GraphicColorGamut dstGamut,
1512     const std::vector<GraphicHDRMetaData>& metaDatas)
1513 {
1514     bool convertRes = Detail::ConvertBufferColorGamut(newBuffer, buffer, srcGamut, dstGamut, metaDatas);
1515     if (convertRes) {
1516         RS_LOGW("CreateNewColorGamutBitmap: convert color gamut succeed, use new buffer to create bitmap.");
1517         Drawing::BitmapFormat format = GenerateDrawingBitmapFormat(buffer);
1518         bitmap.Build(buffer->GetWidth(), buffer->GetHeight(), format, buffer->GetStride());
1519         bitmap.SetPixels(newBuffer.data());
1520         return true;
1521     } else {
1522         RS_LOGW("CreateNewColorGamutBitmap: convert color gamut failed, use old buffer to create bitmap.");
1523         return CreateBitmap(buffer, bitmap);
1524     }
1525 }
1526 
1527 pid_t RSBaseRenderUtil::lastSendingPid_ = 0;
1528 
ParseTransactionData(MessageParcel & parcel,uint32_t parcelNumber)1529 std::unique_ptr<RSTransactionData> RSBaseRenderUtil::ParseTransactionData(
1530     MessageParcel& parcel, uint32_t parcelNumber)
1531 {
1532     RS_TRACE_NAME("UnMarsh RSTransactionData: data size:" + std::to_string(parcel.GetDataSize()));
1533     auto transactionData = parcel.ReadParcelable<RSTransactionData>();
1534     if (!transactionData) {
1535         RS_TRACE_NAME("UnMarsh RSTransactionData fail!");
1536         RS_LOGE("UnMarsh RSTransactionData fail!");
1537         return nullptr;
1538     }
1539     lastSendingPid_ = transactionData->GetSendingPid();
1540     transactionData->ProfilerPushOffsets(parcel, parcelNumber);
1541     RS_TRACE_NAME("UnMarsh RSTransactionData: recv data from " + std::to_string(lastSendingPid_));
1542     std::unique_ptr<RSTransactionData> transData(transactionData);
1543     return transData;
1544 }
1545 
WriteSurfaceRenderNodeToPng(const RSSurfaceRenderNode & node)1546 bool RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(const RSSurfaceRenderNode& node)
1547 {
1548     auto type = RSSystemProperties::GetDumpSurfaceType();
1549     if (type != DumpSurfaceType::SINGLESURFACE && type != DumpSurfaceType::ALLSURFACES) {
1550         return false;
1551     }
1552     uint64_t id = static_cast<uint64_t>(RSSystemProperties::GetDumpSurfaceId());
1553     if (type == DumpSurfaceType::SINGLESURFACE && !ROSEN_EQ(node.GetId(), id)) {
1554         return false;
1555     }
1556     sptr<SurfaceBuffer> buffer = node.GetRSSurfaceHandler()->GetBuffer();
1557     if (!buffer) {
1558         return false;
1559     }
1560     BufferHandle *bufferHandle =  buffer->GetBufferHandle();
1561     if (bufferHandle == nullptr) {
1562         return false;
1563     }
1564 
1565     int64_t nowVal = GenerateCurrentTimeStamp();
1566     std::string filename = "/data/SurfaceRenderNode_" +
1567         node.GetName() + "_"  +
1568         std::to_string(node.GetId()) + "_" +
1569         std::to_string(nowVal) + ".png";
1570     WriteToPngParam param;
1571     param.width = static_cast<uint32_t>(bufferHandle->width);
1572     param.height = static_cast<uint32_t>(bufferHandle->height);
1573     param.data = static_cast<uint8_t *>(buffer->GetVirAddr());
1574     param.stride = static_cast<uint32_t>(bufferHandle->stride);
1575     param.bitDepth = Detail::BITMAP_DEPTH;
1576 
1577     return WriteToPng(filename, param);
1578 }
1579 
WriteCacheRenderNodeToPng(const RSRenderNode & node)1580 bool RSBaseRenderUtil::WriteCacheRenderNodeToPng(const RSRenderNode& node)
1581 {
1582     auto type = RSSystemProperties::GetDumpSurfaceType();
1583     if (type != DumpSurfaceType::SINGLESURFACE && type != DumpSurfaceType::ALLSURFACES) {
1584         return false;
1585     }
1586     uint64_t id = static_cast<uint64_t>(RSSystemProperties::GetDumpSurfaceId());
1587     if (type == DumpSurfaceType::SINGLESURFACE && !ROSEN_EQ(node.GetId(), id)) {
1588         return false;
1589     }
1590     std::shared_ptr<Drawing::Surface> surface = node.GetCacheSurface();
1591     if (!surface) {
1592         return false;
1593     }
1594 
1595     int64_t nowVal = GenerateCurrentTimeStamp();
1596     std::string filename = "/data/CacheRenderNode_" +
1597         std::to_string(node.GetId()) + "_" +
1598         std::to_string(nowVal) + ".png";
1599     WriteToPngParam param;
1600 
1601     auto image = surface->GetImageSnapshot();
1602     if (!image) {
1603         return false;
1604     }
1605     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
1606     Drawing::Bitmap bitmap;
1607     bitmap.Build(image->GetWidth(), image->GetHeight(), format);
1608     image->ReadPixels(bitmap, 0, 0);
1609     param.width = static_cast<uint32_t>(image->GetWidth());
1610     param.height = static_cast<uint32_t>(image->GetHeight());
1611     param.data = static_cast<uint8_t *>(bitmap.GetPixels());
1612     param.stride = static_cast<uint32_t>(bitmap.GetRowBytes());
1613     param.bitDepth = Detail::BITMAP_DEPTH;
1614 
1615     return WriteToPng(filename, param);
1616 }
1617 
WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Surface> surface,std::string debugInfo)1618 bool RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Surface> surface, std::string debugInfo)
1619 {
1620     if (!RSSystemProperties::GetDumpImgEnabled()) {
1621         return false;
1622     }
1623     if (!surface) {
1624         return false;
1625     }
1626 
1627     // create dir if not exists
1628     if (access(DUMP_CACHESURFACE_DIR.c_str(), F_OK) == -1) {
1629         if (mkdir(DUMP_CACHESURFACE_DIR.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
1630             RS_LOGE("WriteCacheImageRenderNodeToPng create %s directory failed, errno: %d",
1631                 DUMP_CACHESURFACE_DIR.c_str(), errno);
1632             return false;
1633         }
1634     }
1635     const uint32_t maxLen = 80;
1636     time_t now = time(nullptr);
1637     tm* curr_tm = localtime(&now);
1638     if (curr_tm == nullptr) {
1639         RS_LOGE("WriteCacheImageRenderNodeToPng localtime returns null");
1640         return false;
1641     }
1642     char timechar[maxLen] = {0};
1643     (void)strftime(timechar, maxLen, "%Y%m%d%H%M%S", curr_tm);
1644     std::string filename = DUMP_CACHESURFACE_DIR + "/" + "CacheRenderNode_Draw_"
1645         + std::string(timechar) + "_" + debugInfo + ".png";
1646     WriteToPngParam param;
1647 
1648     auto image = surface->GetImageSnapshot();
1649     if (!image) {
1650         RS_LOGE("RSSubThread::DrawableCache no image to dump");
1651         return false;
1652     }
1653     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
1654     Drawing::Bitmap bitmap;
1655     bitmap.Build(image->GetWidth(), image->GetHeight(), format);
1656     image->ReadPixels(bitmap, 0, 0);
1657     param.width = static_cast<uint32_t>(image->GetWidth());
1658     param.height = static_cast<uint32_t>(image->GetHeight());
1659     param.data = static_cast<uint8_t *>(bitmap.GetPixels());
1660     param.stride = static_cast<uint32_t>(bitmap.GetRowBytes());
1661     param.bitDepth = Detail::BITMAP_DEPTH;
1662 
1663     return WriteToPng(filename, param);
1664 }
1665 
WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Bitmap> bitmap,std::string debugInfo)1666 bool RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Bitmap> bitmap, std::string debugInfo)
1667 {
1668     if (!bitmap) {
1669         RS_LOGE("RSSubThread::DrawableCache no bitmap to dump");
1670         return false;
1671     }
1672     // create dir if not exists
1673     if (access(DUMP_CANVASDRAWING_DIR.c_str(), F_OK) == -1) {
1674         if (mkdir(DUMP_CANVASDRAWING_DIR.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
1675             RS_LOGE("DumpImageDrawingToPng create %s directory failed, errno: %d",
1676                 DUMP_CANVASDRAWING_DIR.c_str(), errno);
1677             return false;
1678         }
1679     }
1680     const uint32_t maxLen = 80;
1681     time_t now = time(nullptr);
1682     tm* curr_tm = localtime(&now);
1683     char timechar[maxLen] = {0};
1684     (void)strftime(timechar, maxLen, "%Y%m%d%H%M%S", curr_tm);
1685     std::string filename = DUMP_CANVASDRAWING_DIR + "/" + "CacheRenderNode_Draw_"
1686         + std::string(timechar) + "_" + debugInfo + ".png";
1687 
1688     WriteToPngParam param;
1689     param.width = static_cast<uint32_t>(bitmap->GetWidth());
1690     param.height = static_cast<uint32_t>(bitmap->GetHeight());
1691     param.data = static_cast<uint8_t *>(bitmap->GetPixels());
1692     param.stride = static_cast<uint32_t>(bitmap->GetRowBytes());
1693     param.bitDepth = Detail::BITMAP_DEPTH;
1694 
1695     return WriteToPng(filename, param);
1696 }
1697 
WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Image> image,std::string debugInfo)1698 bool RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Image> image, std::string debugInfo)
1699 {
1700     if (!RSSystemProperties::GetDumpImgEnabled()) {
1701         return false;
1702     }
1703 
1704     // create dir if not exists
1705     if (access(DUMP_CACHESURFACE_DIR.c_str(), F_OK) == -1) {
1706         if (mkdir(DUMP_CACHESURFACE_DIR.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
1707             RS_LOGE("WriteCacheImageRenderNodeToPng create %s directory failed, errno: %d",
1708                 DUMP_CACHESURFACE_DIR.c_str(), errno);
1709             return false;
1710         }
1711     }
1712     const uint32_t maxLen = 80;
1713     time_t now = time(nullptr);
1714     tm* curr_tm = localtime(&now);
1715     if (curr_tm == nullptr) {
1716         RS_LOGE("WriteCacheImageRenderNodeToPng localtime returns null");
1717         return false;
1718     }
1719     char timechar[maxLen] = {0};
1720     (void)strftime(timechar, maxLen, "%Y%m%d%H%M%S", curr_tm);
1721     std::string filename = DUMP_CACHESURFACE_DIR + "/" + "CacheRenderNode_Draw_"
1722         + std::string(timechar) + "_" + debugInfo + ".png";
1723     WriteToPngParam param;
1724 
1725     if (!image) {
1726         RS_LOGE("RSSubThread::DrawableCache no image to dump");
1727         return false;
1728     }
1729     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
1730     Drawing::Bitmap bitmap;
1731     bitmap.Build(image->GetWidth(), image->GetHeight(), format);
1732     image->ReadPixels(bitmap, 0, 0);
1733     param.width = static_cast<uint32_t>(image->GetWidth());
1734     param.height = static_cast<uint32_t>(image->GetHeight());
1735     param.data = static_cast<uint8_t *>(bitmap.GetPixels());
1736     param.stride = static_cast<uint32_t>(bitmap.GetRowBytes());
1737     param.bitDepth = Detail::BITMAP_DEPTH;
1738 
1739     return WriteToPng(filename, param);
1740 }
1741 
WritePixelMapToPng(Media::PixelMap & pixelMap)1742 bool RSBaseRenderUtil::WritePixelMapToPng(Media::PixelMap& pixelMap)
1743 {
1744     auto type = RSSystemProperties::GetDumpSurfaceType();
1745     if (type != DumpSurfaceType::PIXELMAP) {
1746         return false;
1747     }
1748     int64_t nowVal = GenerateCurrentTimeStamp();
1749     std::string filename = "/data/PixelMap_" + std::to_string(nowVal) + ".png";
1750 
1751     WriteToPngParam param;
1752     param.width = static_cast<uint32_t>(pixelMap.GetWidth());
1753     param.height = static_cast<uint32_t>(pixelMap.GetHeight());
1754     param.data = pixelMap.GetPixels();
1755     param.stride = static_cast<uint32_t>(pixelMap.GetRowStride());
1756     param.bitDepth = Detail::BITMAP_DEPTH;
1757 
1758     return WriteToPng(filename, param);
1759 }
1760 
WriteSurfaceBufferToPng(sptr<SurfaceBuffer> & buffer,uint64_t id)1761 bool RSBaseRenderUtil::WriteSurfaceBufferToPng(sptr<SurfaceBuffer>& buffer, uint64_t id)
1762 {
1763     auto type = RSSystemProperties::GetDumpSurfaceType();
1764     if (type != DumpSurfaceType::SURFACEBUFFER) {
1765         return false;
1766     }
1767     if (!buffer) {
1768         RS_LOGE("RSBaseRenderUtil::WriteSurfaceBufferToPng buffer is nullptr");
1769         return false;
1770     }
1771 
1772     int64_t nowVal = GenerateCurrentTimeStamp();
1773     std::string filename = "/data/SurfaceBuffer_" + std::to_string(id) + "_" + std::to_string(nowVal) + ".png";
1774     BufferHandle *bufferHandle = buffer->GetBufferHandle();
1775     if (bufferHandle == nullptr) {
1776         RS_LOGE("RSBaseRenderUtil::WriteSurfaceBufferToPng bufferHandle is nullptr");
1777         return false;
1778     }
1779     WriteToPngParam param;
1780     param.width = static_cast<uint32_t>(bufferHandle->width);
1781     param.height = static_cast<uint32_t>(bufferHandle->height);
1782     param.data = static_cast<uint8_t *>(buffer->GetVirAddr());
1783     param.stride = static_cast<uint32_t>(bufferHandle->stride);
1784     param.bitDepth = Detail::BITMAP_DEPTH;
1785 
1786     return WriteToPng(filename, param);
1787 }
1788 
WriteToPng(const std::string & filename,const WriteToPngParam & param)1789 bool RSBaseRenderUtil::WriteToPng(const std::string &filename, const WriteToPngParam &param)
1790 {
1791     if (filename.empty()) {
1792         RS_LOGI("RSBaseRenderUtil::WriteToPng filename is empty");
1793         return false;
1794     }
1795     RS_LOGI("RSBaseRenderUtil::WriteToPng filename = %{public}s", filename.c_str());
1796     png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
1797     if (pngStruct == nullptr) {
1798         return false;
1799     }
1800     png_infop pngInfo = png_create_info_struct(pngStruct);
1801     if (pngInfo == nullptr) {
1802         RS_LOGE("RSBaseRenderUtil::WriteDataPng fail, pngInfo is nullptr");
1803         png_destroy_write_struct(&pngStruct, nullptr);
1804         return false;
1805     }
1806 
1807     FILE *fp = fopen(filename.c_str(), "wb");
1808     if (fp == nullptr) {
1809         png_destroy_write_struct(&pngStruct, &pngInfo);
1810         RS_LOGE("WriteToPng file: %s open file failed, errno: %d", filename.c_str(), errno);
1811         return false;
1812     }
1813     png_init_io(pngStruct, fp);
1814 
1815     // set png header
1816     png_set_IHDR(pngStruct, pngInfo,
1817         param.width, param.height,
1818         param.bitDepth,
1819         PNG_COLOR_TYPE_RGBA,
1820         PNG_INTERLACE_NONE,
1821         PNG_COMPRESSION_TYPE_BASE,
1822         PNG_FILTER_TYPE_BASE);
1823     png_set_packing(pngStruct); // set packing info
1824     png_write_info(pngStruct, pngInfo); // write to header
1825 
1826     for (uint32_t i = 0; i < param.height; i++) {
1827         png_write_row(pngStruct, param.data + (i * param.stride));
1828     }
1829     png_write_end(pngStruct, pngInfo);
1830 
1831     // free
1832     png_destroy_write_struct(&pngStruct, &pngInfo);
1833     int ret = fclose(fp);
1834     return ret == 0;
1835 }
1836 
GetRotateTransform(GraphicTransformType transform)1837 GraphicTransformType RSBaseRenderUtil::GetRotateTransform(GraphicTransformType transform)
1838 {
1839     switch (transform) {
1840         case GraphicTransformType::GRAPHIC_FLIP_H:
1841         case GraphicTransformType::GRAPHIC_FLIP_V: {
1842             return GraphicTransformType::GRAPHIC_ROTATE_NONE;
1843         }
1844         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
1845         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90: {
1846             return GraphicTransformType::GRAPHIC_ROTATE_90;
1847         }
1848         case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
1849         case GraphicTransformType::GRAPHIC_FLIP_V_ROT180: {
1850             return GraphicTransformType::GRAPHIC_ROTATE_180;
1851         }
1852         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270:
1853         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270: {
1854             return GraphicTransformType::GRAPHIC_ROTATE_270;
1855         }
1856         default: {
1857             return transform;
1858         }
1859     }
1860 }
1861 
GetFlipTransform(GraphicTransformType transform)1862 GraphicTransformType RSBaseRenderUtil::GetFlipTransform(GraphicTransformType transform)
1863 {
1864     switch (transform) {
1865         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
1866         case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
1867         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270: {
1868             return GraphicTransformType::GRAPHIC_FLIP_H;
1869         }
1870         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90:
1871         case GraphicTransformType::GRAPHIC_FLIP_V_ROT180:
1872         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270: {
1873             return GraphicTransformType::GRAPHIC_FLIP_V;
1874         }
1875         default: {
1876             return transform;
1877         }
1878     }
1879 }
1880 
ClockwiseToAntiClockwiseTransform(GraphicTransformType transform)1881 GraphicTransformType RSBaseRenderUtil::ClockwiseToAntiClockwiseTransform(GraphicTransformType transform)
1882 {
1883     switch (transform) {
1884         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1885             return GraphicTransformType::GRAPHIC_ROTATE_270;
1886         }
1887         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1888             return GraphicTransformType::GRAPHIC_ROTATE_90;
1889         }
1890         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90: {
1891             return GraphicTransformType::GRAPHIC_FLIP_V_ROT90;
1892         }
1893         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270: {
1894             return GraphicTransformType::GRAPHIC_FLIP_V_ROT270;
1895         }
1896         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90: {
1897             return GraphicTransformType::GRAPHIC_FLIP_H_ROT90;
1898         }
1899         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270: {
1900             return GraphicTransformType::GRAPHIC_FLIP_H_ROT270;
1901         }
1902         default: {
1903             return transform;
1904         }
1905     }
1906 }
1907 
RotateEnumToInt(ScreenRotation rotation)1908 int RSBaseRenderUtil::RotateEnumToInt(ScreenRotation rotation)
1909 {
1910     static const std::map<ScreenRotation, int> screenRotationEnumToIntMap = {
1911         {ScreenRotation::ROTATION_0, 0}, {ScreenRotation::ROTATION_90, 90},
1912         {ScreenRotation::ROTATION_180, 180}, {ScreenRotation::ROTATION_270, 270}};
1913     auto iter = screenRotationEnumToIntMap.find(rotation);
1914     return iter != screenRotationEnumToIntMap.end() ? iter->second : 0;
1915 }
1916 
RotateEnumToInt(GraphicTransformType rotation)1917 int RSBaseRenderUtil::RotateEnumToInt(GraphicTransformType rotation)
1918 {
1919     static const std::map<GraphicTransformType, int> transformTypeEnumToIntMap = {
1920         {GraphicTransformType::GRAPHIC_ROTATE_NONE, 0}, {GraphicTransformType::GRAPHIC_ROTATE_90, 90},
1921         {GraphicTransformType::GRAPHIC_ROTATE_180, 180}, {GraphicTransformType::GRAPHIC_ROTATE_270, 270}};
1922     auto iter = transformTypeEnumToIntMap.find(rotation);
1923     return iter != transformTypeEnumToIntMap.end() ? iter->second : 0;
1924 }
1925 
RotateEnumToInt(int angle,GraphicTransformType flip)1926 GraphicTransformType RSBaseRenderUtil::RotateEnumToInt(int angle, GraphicTransformType flip)
1927 {
1928     static const std::map<int, GraphicTransformType> intToEnumMap = {
1929         {0, GraphicTransformType::GRAPHIC_ROTATE_NONE}, {90, GraphicTransformType::GRAPHIC_ROTATE_270},
1930         {180, GraphicTransformType::GRAPHIC_ROTATE_180}, {270, GraphicTransformType::GRAPHIC_ROTATE_90}};
1931     static const std::map<std::pair<int, GraphicTransformType>, GraphicTransformType> pairToEnumMap = {
1932         {{0, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_H},
1933         {{0, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_V},
1934         {{90, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_V_ROT90},
1935         {{90, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_H_ROT90},
1936         {{180, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_V},
1937         {{180, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_H},
1938         {{270, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_H_ROT90},
1939         {{270, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_V_ROT90},
1940     };
1941 
1942     if (flip != GraphicTransformType::GRAPHIC_FLIP_H && flip != GraphicTransformType::GRAPHIC_FLIP_V) {
1943         auto iter = intToEnumMap.find(angle);
1944         return iter != intToEnumMap.end() ? iter->second : GraphicTransformType::GRAPHIC_ROTATE_NONE;
1945     } else {
1946         auto iter = pairToEnumMap.find({angle, flip});
1947         return iter != pairToEnumMap.end() ? iter->second : GraphicTransformType::GRAPHIC_ROTATE_NONE;
1948     }
1949 }
1950 
GetAccumulatedBufferCount()1951 int RSBaseRenderUtil::GetAccumulatedBufferCount()
1952 {
1953     return std::max(acquiredBufferCount_ -  1, 0);
1954 }
1955 
IncAcquiredBufferCount()1956 void RSBaseRenderUtil::IncAcquiredBufferCount()
1957 {
1958     ++acquiredBufferCount_;
1959     RS_TRACE_NAME_FMT("Inc Acq BufferCount %d", acquiredBufferCount_.load());
1960 }
1961 
DecAcquiredBufferCount()1962 void RSBaseRenderUtil::DecAcquiredBufferCount()
1963 {
1964     --acquiredBufferCount_;
1965     RS_TRACE_NAME_FMT("Dec Acq BufferCount %d", acquiredBufferCount_.load());
1966 }
1967 
GetLastSendingPid()1968 pid_t RSBaseRenderUtil::GetLastSendingPid()
1969 {
1970     return lastSendingPid_;
1971 }
1972 
1973 } // namespace Rosen
1974 } // namespace OHOS
1975