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