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