• 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 "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 isProtected,GraphicColorGamut colorGamut,GraphicPixelFormat pixelFormat)863 BufferRequestConfig RSBaseRenderUtil::GetFrameBufferRequestConfig(const ScreenInfo& screenInfo,
864     bool isProtected, GraphicColorGamut colorGamut, GraphicPixelFormat pixelFormat)
865 {
866     BufferRequestConfig config {};
867     auto width = screenInfo.isSamplingOn ? screenInfo.phyWidth : screenInfo.width;
868     auto height = screenInfo.isSamplingOn ? screenInfo.phyHeight : screenInfo.height;
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 = colorGamut;
873     config.format = 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>(round(nodeParams->GetAbsRotation()));
1324         extraRotation = (degree - rotationDegree) % ROUND_ANGLE;
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     if (UNLIKELY(params.hasCropMetadata)) {
1350         params.dstRect = Drawing::Rect(0, 0,
1351             params.buffer->GetSurfaceBufferWidth(), params.buffer->GetSurfaceBufferHeight());
1352     } else {
1353         params.dstRect = params.srcRect;
1354     }
1355 }
1356 
FlipMatrix(GraphicTransformType transform,BufferDrawParam & params)1357 void RSBaseRenderUtil::FlipMatrix(GraphicTransformType transform, BufferDrawParam& params)
1358 {
1359     GraphicTransformType type = GetFlipTransform(transform);
1360     if (type != GraphicTransformType::GRAPHIC_FLIP_H && type != GraphicTransformType::GRAPHIC_FLIP_V) {
1361         return;
1362     }
1363 
1364     const int angle = 180;
1365     Drawing::Camera3D camera3D;
1366     switch (type) {
1367         case GraphicTransformType::GRAPHIC_FLIP_H: {
1368             camera3D.RotateYDegrees(angle);
1369             break;
1370         }
1371         case GraphicTransformType::GRAPHIC_FLIP_V: {
1372             camera3D.RotateXDegrees(angle);
1373             break;
1374         }
1375         default: {
1376             return;
1377         }
1378     }
1379     RS_LOGD("RSBaseRenderUtil::FlipMatrix %{public}d", transform);
1380     Drawing::Matrix flip;
1381     camera3D.ApplyToMatrix(flip);
1382     const float half = 0.5f;
1383     flip.PreTranslate(-half * params.dstRect.GetWidth(), -half * params.dstRect.GetHeight());
1384     flip.PostTranslate(half * params.dstRect.GetWidth(), half * params.dstRect.GetHeight());
1385     params.matrix.PreConcat(flip);
1386 }
1387 
SetPropertiesForCanvas(RSPaintFilterCanvas & canvas,const BufferDrawParam & params)1388 void RSBaseRenderUtil::SetPropertiesForCanvas(RSPaintFilterCanvas& canvas, const BufferDrawParam& params)
1389 {
1390     if (params.isNeedClip) {
1391         if (!params.cornerRadius.IsZero()) {
1392             canvas.ClipRoundRect(
1393                 RSPropertiesPainter::RRect2DrawingRRect(params.clipRRect), Drawing::ClipOp::INTERSECT, true);
1394         } else {
1395             canvas.ClipRect(params.clipRect, Drawing::ClipOp::INTERSECT, false);
1396         }
1397     }
1398     if (Drawing::Color::ColorQuadGetA(params.backgroundColor) != Drawing::Color::COLOR_TRANSPARENT) {
1399         canvas.DrawColor(params.backgroundColor);
1400     }
1401     canvas.ConcatMatrix(params.matrix);
1402 }
1403 
ConvertBufferToBitmap(sptr<SurfaceBuffer> buffer,std::vector<uint8_t> & newBuffer,GraphicColorGamut dstGamut,Drawing::Bitmap & bitmap,const std::vector<GraphicHDRMetaData> & metaDatas)1404 bool RSBaseRenderUtil::ConvertBufferToBitmap(sptr<SurfaceBuffer> buffer, std::vector<uint8_t>& newBuffer,
1405     GraphicColorGamut dstGamut, Drawing::Bitmap& bitmap, const std::vector<GraphicHDRMetaData>& metaDatas)
1406 {
1407     if (!IsBufferValid(buffer)) {
1408         return false;
1409     }
1410     bool bitmapCreated = false;
1411     GraphicColorGamut srcGamut = static_cast<GraphicColorGamut>(buffer->GetSurfaceBufferColorGamut());
1412     // [PLANNING]: We will not use this tmp newBuffer if we use GPU to do the color conversions.
1413     // Attention: make sure newBuffer's lifecycle is longer than the moment call drawBitmap
1414     if (buffer->GetFormat() == GRAPHIC_PIXEL_FMT_YCRCB_420_SP ||
1415         buffer->GetFormat() == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
1416         bitmapCreated = CreateYuvToRGBABitMap(buffer, newBuffer, bitmap);
1417     } else if (buffer->GetFormat() == Detail::STUB_PIXEL_FMT_RGBA_16161616) {
1418         bitmapCreated = CreateNewColorGamutBitmap(buffer, newBuffer, bitmap, srcGamut, dstGamut, metaDatas);
1419     } else if (srcGamut != dstGamut) {
1420         RS_LOGD("RSBaseRenderUtil::ConvertBufferToBitmap: need to convert color gamut.");
1421         bitmapCreated = CreateNewColorGamutBitmap(buffer, newBuffer, bitmap, srcGamut, dstGamut);
1422     } else {
1423         bitmapCreated = CreateBitmap(buffer, bitmap);
1424     }
1425     return bitmapCreated;
1426 }
1427 
CreateYuvToRGBABitMap(sptr<OHOS::SurfaceBuffer> buffer,std::vector<uint8_t> & newBuffer,Drawing::Bitmap & bitmap)1428 bool RSBaseRenderUtil::CreateYuvToRGBABitMap(sptr<OHOS::SurfaceBuffer> buffer, std::vector<uint8_t>& newBuffer,
1429     Drawing::Bitmap& bitmap)
1430 {
1431     newBuffer.resize(buffer->GetWidth() * buffer->GetHeight() * 4, 0); // 4 is color channel
1432     if (!Detail::ConvertYUV420SPToRGBA(newBuffer, buffer)) {
1433         return false;
1434     }
1435 
1436     Drawing::ImageInfo imageInfo(buffer->GetWidth(), buffer->GetHeight(),
1437         Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL);
1438     bitmap.InstallPixels(imageInfo, newBuffer.data(), buffer->GetWidth() * 4);
1439     return true;
1440 }
1441 
CreateBitmap(sptr<OHOS::SurfaceBuffer> buffer,Drawing::Bitmap & bitmap)1442 bool RSBaseRenderUtil::CreateBitmap(sptr<OHOS::SurfaceBuffer> buffer, Drawing::Bitmap& bitmap)
1443 {
1444     Drawing::BitmapFormat format = GenerateDrawingBitmapFormat(buffer);
1445     bitmap.Build(buffer->GetWidth(), buffer->GetHeight(), format, buffer->GetStride());
1446     bitmap.SetPixels(buffer->GetVirAddr());
1447     return true;
1448 }
1449 
GenerateDrawingBitmapFormat(const sptr<OHOS::SurfaceBuffer> & buffer)1450 Drawing::BitmapFormat RSBaseRenderUtil::GenerateDrawingBitmapFormat(const sptr<OHOS::SurfaceBuffer>& buffer)
1451 {
1452     Drawing::BitmapFormat format;
1453     if (buffer == nullptr) {
1454         return format;
1455     }
1456     Drawing::ColorType colorType = GetColorTypeFromBufferFormat(buffer->GetFormat());
1457     Drawing::AlphaType alphaType = Drawing::AlphaType::ALPHATYPE_PREMUL;
1458     format = { colorType, alphaType };
1459     return format;
1460 }
1461 
CreateNewColorGamutBitmap(sptr<OHOS::SurfaceBuffer> buffer,std::vector<uint8_t> & newBuffer,Drawing::Bitmap & bitmap,GraphicColorGamut srcGamut,GraphicColorGamut dstGamut,const std::vector<GraphicHDRMetaData> & metaDatas)1462 bool RSBaseRenderUtil::CreateNewColorGamutBitmap(sptr<OHOS::SurfaceBuffer> buffer, std::vector<uint8_t>& newBuffer,
1463     Drawing::Bitmap& bitmap, GraphicColorGamut srcGamut, GraphicColorGamut dstGamut,
1464     const std::vector<GraphicHDRMetaData>& metaDatas)
1465 {
1466     bool convertRes = Detail::ConvertBufferColorGamut(newBuffer, buffer, srcGamut, dstGamut, metaDatas);
1467     if (convertRes) {
1468         RS_LOGW("CreateNewColorGamutBitmap: convert color gamut succeed, use new buffer to create bitmap.");
1469         Drawing::BitmapFormat format = GenerateDrawingBitmapFormat(buffer);
1470         bitmap.Build(buffer->GetWidth(), buffer->GetHeight(), format, buffer->GetStride());
1471         bitmap.SetPixels(newBuffer.data());
1472         return true;
1473     } else {
1474         RS_LOGW("CreateNewColorGamutBitmap: convert color gamut failed, use old buffer to create bitmap.");
1475         return CreateBitmap(buffer, bitmap);
1476     }
1477 }
1478 
1479 pid_t RSBaseRenderUtil::lastSendingPid_ = 0;
1480 
ParseTransactionData(MessageParcel & parcel)1481 std::unique_ptr<RSTransactionData> RSBaseRenderUtil::ParseTransactionData(MessageParcel& parcel)
1482 {
1483     RS_TRACE_NAME("UnMarsh RSTransactionData: data size:" + std::to_string(parcel.GetDataSize()));
1484     auto transactionData = parcel.ReadParcelable<RSTransactionData>();
1485     if (!transactionData) {
1486         RS_TRACE_NAME("UnMarsh RSTransactionData fail!");
1487         RS_LOGE("UnMarsh RSTransactionData fail!");
1488         return nullptr;
1489     }
1490     lastSendingPid_ = transactionData->GetSendingPid();
1491     RS_TRACE_NAME("UnMarsh RSTransactionData: recv data from " + std::to_string(lastSendingPid_));
1492     std::unique_ptr<RSTransactionData> transData(transactionData);
1493     return transData;
1494 }
1495 
WriteSurfaceRenderNodeToPng(const RSSurfaceRenderNode & node)1496 bool RSBaseRenderUtil::WriteSurfaceRenderNodeToPng(const RSSurfaceRenderNode& node)
1497 {
1498     auto type = RSSystemProperties::GetDumpSurfaceType();
1499     if (type != DumpSurfaceType::SINGLESURFACE && type != DumpSurfaceType::ALLSURFACES) {
1500         return false;
1501     }
1502     uint64_t id = static_cast<uint64_t>(RSSystemProperties::GetDumpSurfaceId());
1503     if (type == DumpSurfaceType::SINGLESURFACE && !ROSEN_EQ(node.GetId(), id)) {
1504         return false;
1505     }
1506     sptr<SurfaceBuffer> buffer = node.GetRSSurfaceHandler()->GetBuffer();
1507     if (!buffer) {
1508         return false;
1509     }
1510     BufferHandle *bufferHandle =  buffer->GetBufferHandle();
1511     if (bufferHandle == nullptr) {
1512         return false;
1513     }
1514 
1515     int64_t nowVal = GenerateCurrentTimeStamp();
1516     std::string filename = "/data/SurfaceRenderNode_" +
1517         node.GetName() + "_"  +
1518         std::to_string(node.GetId()) + "_" +
1519         std::to_string(nowVal) + ".png";
1520     WriteToPngParam param;
1521     param.width = static_cast<uint32_t>(bufferHandle->width);
1522     param.height = static_cast<uint32_t>(bufferHandle->height);
1523     param.data = static_cast<uint8_t *>(buffer->GetVirAddr());
1524     param.stride = static_cast<uint32_t>(bufferHandle->stride);
1525     param.bitDepth = Detail::BITMAP_DEPTH;
1526 
1527     return WriteToPng(filename, param);
1528 }
1529 
WriteCacheRenderNodeToPng(const RSRenderNode & node)1530 bool RSBaseRenderUtil::WriteCacheRenderNodeToPng(const RSRenderNode& node)
1531 {
1532     auto type = RSSystemProperties::GetDumpSurfaceType();
1533     if (type != DumpSurfaceType::SINGLESURFACE && type != DumpSurfaceType::ALLSURFACES) {
1534         return false;
1535     }
1536     uint64_t id = static_cast<uint64_t>(RSSystemProperties::GetDumpSurfaceId());
1537     if (type == DumpSurfaceType::SINGLESURFACE && !ROSEN_EQ(node.GetId(), id)) {
1538         return false;
1539     }
1540     std::shared_ptr<Drawing::Surface> surface = node.GetCacheSurface();
1541     if (!surface) {
1542         return false;
1543     }
1544 
1545     int64_t nowVal = GenerateCurrentTimeStamp();
1546     std::string filename = "/data/CacheRenderNode_" +
1547         std::to_string(node.GetId()) + "_" +
1548         std::to_string(nowVal) + ".png";
1549     WriteToPngParam param;
1550 
1551     auto image = surface->GetImageSnapshot();
1552     if (!image) {
1553         return false;
1554     }
1555     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
1556     Drawing::Bitmap bitmap;
1557     bitmap.Build(image->GetWidth(), image->GetHeight(), format);
1558     image->ReadPixels(bitmap, 0, 0);
1559     param.width = static_cast<uint32_t>(image->GetWidth());
1560     param.height = static_cast<uint32_t>(image->GetHeight());
1561     param.data = static_cast<uint8_t *>(bitmap.GetPixels());
1562     param.stride = static_cast<uint32_t>(bitmap.GetRowBytes());
1563     param.bitDepth = Detail::BITMAP_DEPTH;
1564 
1565     return WriteToPng(filename, param);
1566 }
1567 
WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Surface> surface,std::string debugInfo)1568 bool RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Surface> surface, std::string debugInfo)
1569 {
1570     if (!RSSystemProperties::GetDumpImgEnabled()) {
1571         return false;
1572     }
1573     if (!surface) {
1574         return false;
1575     }
1576 
1577     // create dir if not exists
1578     if (access(DUMP_CACHESURFACE_DIR.c_str(), F_OK) == -1) {
1579         if (mkdir(DUMP_CACHESURFACE_DIR.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
1580             RS_LOGE("WriteCacheImageRenderNodeToPng create %s directory failed, errno: %d",
1581                 DUMP_CACHESURFACE_DIR.c_str(), errno);
1582             return false;
1583         }
1584     }
1585     const uint32_t maxLen = 80;
1586     time_t now = time(nullptr);
1587     tm* curr_tm = localtime(&now);
1588     if (curr_tm == nullptr) {
1589         RS_LOGE("WriteCacheImageRenderNodeToPng localtime returns null");
1590         return false;
1591     }
1592     char timechar[maxLen] = {0};
1593     (void)strftime(timechar, maxLen, "%Y%m%d%H%M%S", curr_tm);
1594     std::string filename = DUMP_CACHESURFACE_DIR + "/" + "CacheRenderNode_Draw_"
1595         + std::string(timechar) + "_" + debugInfo + ".png";
1596     WriteToPngParam param;
1597 
1598     auto image = surface->GetImageSnapshot();
1599     if (!image) {
1600         RS_LOGE("RSSubThread::DrawableCache no image to dump");
1601         return false;
1602     }
1603     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
1604     Drawing::Bitmap bitmap;
1605     bitmap.Build(image->GetWidth(), image->GetHeight(), format);
1606     image->ReadPixels(bitmap, 0, 0);
1607     param.width = static_cast<uint32_t>(image->GetWidth());
1608     param.height = static_cast<uint32_t>(image->GetHeight());
1609     param.data = static_cast<uint8_t *>(bitmap.GetPixels());
1610     param.stride = static_cast<uint32_t>(bitmap.GetRowBytes());
1611     param.bitDepth = Detail::BITMAP_DEPTH;
1612 
1613     return WriteToPng(filename, param);
1614 }
1615 
WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Image> image,std::string debugInfo)1616 bool RSBaseRenderUtil::WriteCacheImageRenderNodeToPng(std::shared_ptr<Drawing::Image> image, std::string debugInfo)
1617 {
1618     if (!RSSystemProperties::GetDumpImgEnabled()) {
1619         return false;
1620     }
1621 
1622     // create dir if not exists
1623     if (access(DUMP_CACHESURFACE_DIR.c_str(), F_OK) == -1) {
1624         if (mkdir(DUMP_CACHESURFACE_DIR.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
1625             RS_LOGE("WriteCacheImageRenderNodeToPng create %s directory failed, errno: %d",
1626                 DUMP_CACHESURFACE_DIR.c_str(), errno);
1627             return false;
1628         }
1629     }
1630     const uint32_t maxLen = 80;
1631     time_t now = time(nullptr);
1632     tm* curr_tm = localtime(&now);
1633     if (curr_tm == nullptr) {
1634         RS_LOGE("WriteCacheImageRenderNodeToPng localtime returns null");
1635         return false;
1636     }
1637     char timechar[maxLen] = {0};
1638     (void)strftime(timechar, maxLen, "%Y%m%d%H%M%S", curr_tm);
1639     std::string filename = DUMP_CACHESURFACE_DIR + "/" + "CacheRenderNode_Draw_"
1640         + std::string(timechar) + "_" + debugInfo + ".png";
1641     WriteToPngParam param;
1642 
1643     if (!image) {
1644         RS_LOGE("RSSubThread::DrawableCache no image to dump");
1645         return false;
1646     }
1647     Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
1648     Drawing::Bitmap bitmap;
1649     bitmap.Build(image->GetWidth(), image->GetHeight(), format);
1650     image->ReadPixels(bitmap, 0, 0);
1651     param.width = static_cast<uint32_t>(image->GetWidth());
1652     param.height = static_cast<uint32_t>(image->GetHeight());
1653     param.data = static_cast<uint8_t *>(bitmap.GetPixels());
1654     param.stride = static_cast<uint32_t>(bitmap.GetRowBytes());
1655     param.bitDepth = Detail::BITMAP_DEPTH;
1656 
1657     return WriteToPng(filename, param);
1658 }
1659 
WritePixelMapToPng(Media::PixelMap & pixelMap)1660 bool RSBaseRenderUtil::WritePixelMapToPng(Media::PixelMap& pixelMap)
1661 {
1662     auto type = RSSystemProperties::GetDumpSurfaceType();
1663     if (type != DumpSurfaceType::PIXELMAP) {
1664         return false;
1665     }
1666     int64_t nowVal = GenerateCurrentTimeStamp();
1667     std::string filename = "/data/PixelMap_" + std::to_string(nowVal) + ".png";
1668 
1669     WriteToPngParam param;
1670     param.width = static_cast<uint32_t>(pixelMap.GetWidth());
1671     param.height = static_cast<uint32_t>(pixelMap.GetHeight());
1672     param.data = pixelMap.GetPixels();
1673     param.stride = static_cast<uint32_t>(pixelMap.GetRowBytes());
1674     param.bitDepth = Detail::BITMAP_DEPTH;
1675 
1676     return WriteToPng(filename, param);
1677 }
1678 
WriteSurfaceBufferToPng(sptr<SurfaceBuffer> & buffer,uint64_t id)1679 bool RSBaseRenderUtil::WriteSurfaceBufferToPng(sptr<SurfaceBuffer>& buffer, uint64_t id)
1680 {
1681     auto type = RSSystemProperties::GetDumpSurfaceType();
1682     if (type != DumpSurfaceType::SURFACEBUFFER) {
1683         return false;
1684     }
1685     if (!buffer) {
1686         RS_LOGE("RSBaseRenderUtil::WriteSurfaceBufferToPng buffer is nullptr");
1687         return false;
1688     }
1689 
1690     int64_t nowVal = GenerateCurrentTimeStamp();
1691     std::string filename = "/data/SurfaceBuffer_" + std::to_string(id) + "_" + std::to_string(nowVal) + ".png";
1692     BufferHandle *bufferHandle = buffer->GetBufferHandle();
1693     if (bufferHandle == nullptr) {
1694         RS_LOGE("RSBaseRenderUtil::WriteSurfaceBufferToPng bufferHandle is nullptr");
1695         return false;
1696     }
1697     WriteToPngParam param;
1698     param.width = static_cast<uint32_t>(bufferHandle->width);
1699     param.height = static_cast<uint32_t>(bufferHandle->height);
1700     param.data = static_cast<uint8_t *>(buffer->GetVirAddr());
1701     param.stride = static_cast<uint32_t>(bufferHandle->stride);
1702     param.bitDepth = Detail::BITMAP_DEPTH;
1703 
1704     return WriteToPng(filename, param);
1705 }
1706 
WriteToPng(const std::string & filename,const WriteToPngParam & param)1707 bool RSBaseRenderUtil::WriteToPng(const std::string &filename, const WriteToPngParam &param)
1708 {
1709     if (filename.empty()) {
1710         RS_LOGI("RSBaseRenderUtil::WriteToPng filename is empty");
1711         return false;
1712     }
1713     RS_LOGI("RSBaseRenderUtil::WriteToPng filename = %{public}s", filename.c_str());
1714     png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
1715     if (pngStruct == nullptr) {
1716         return false;
1717     }
1718     png_infop pngInfo = png_create_info_struct(pngStruct);
1719     if (pngInfo == nullptr) {
1720         png_destroy_write_struct(&pngStruct, nullptr);
1721         return false;
1722     }
1723 
1724     FILE *fp = fopen(filename.c_str(), "wb");
1725     if (fp == nullptr) {
1726         png_destroy_write_struct(&pngStruct, &pngInfo);
1727         RS_LOGE("WriteToPng file: %s open file failed, errno: %d", filename.c_str(), errno);
1728         return false;
1729     }
1730     png_init_io(pngStruct, fp);
1731 
1732     // set png header
1733     png_set_IHDR(pngStruct, pngInfo,
1734         param.width, param.height,
1735         param.bitDepth,
1736         PNG_COLOR_TYPE_RGBA,
1737         PNG_INTERLACE_NONE,
1738         PNG_COMPRESSION_TYPE_BASE,
1739         PNG_FILTER_TYPE_BASE);
1740     png_set_packing(pngStruct); // set packing info
1741     png_write_info(pngStruct, pngInfo); // write to header
1742 
1743     for (uint32_t i = 0; i < param.height; i++) {
1744         png_write_row(pngStruct, param.data + (i * param.stride));
1745     }
1746     png_write_end(pngStruct, pngInfo);
1747 
1748     // free
1749     png_destroy_write_struct(&pngStruct, &pngInfo);
1750     int ret = fclose(fp);
1751     return ret == 0;
1752 }
1753 
GetRotateTransform(GraphicTransformType transform)1754 GraphicTransformType RSBaseRenderUtil::GetRotateTransform(GraphicTransformType transform)
1755 {
1756     switch (transform) {
1757         case GraphicTransformType::GRAPHIC_FLIP_H:
1758         case GraphicTransformType::GRAPHIC_FLIP_V: {
1759             return GraphicTransformType::GRAPHIC_ROTATE_NONE;
1760         }
1761         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
1762         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90: {
1763             return GraphicTransformType::GRAPHIC_ROTATE_90;
1764         }
1765         case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
1766         case GraphicTransformType::GRAPHIC_FLIP_V_ROT180: {
1767             return GraphicTransformType::GRAPHIC_ROTATE_180;
1768         }
1769         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270:
1770         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270: {
1771             return GraphicTransformType::GRAPHIC_ROTATE_270;
1772         }
1773         default: {
1774             return transform;
1775         }
1776     }
1777 }
1778 
GetFlipTransform(GraphicTransformType transform)1779 GraphicTransformType RSBaseRenderUtil::GetFlipTransform(GraphicTransformType transform)
1780 {
1781     switch (transform) {
1782         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90:
1783         case GraphicTransformType::GRAPHIC_FLIP_H_ROT180:
1784         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270: {
1785             return GraphicTransformType::GRAPHIC_FLIP_H;
1786         }
1787         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90:
1788         case GraphicTransformType::GRAPHIC_FLIP_V_ROT180:
1789         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270: {
1790             return GraphicTransformType::GRAPHIC_FLIP_V;
1791         }
1792         default: {
1793             return transform;
1794         }
1795     }
1796 }
1797 
ClockwiseToAntiClockwiseTransform(GraphicTransformType transform)1798 GraphicTransformType RSBaseRenderUtil::ClockwiseToAntiClockwiseTransform(GraphicTransformType transform)
1799 {
1800     switch (transform) {
1801         case GraphicTransformType::GRAPHIC_ROTATE_90: {
1802             return GraphicTransformType::GRAPHIC_ROTATE_270;
1803         }
1804         case GraphicTransformType::GRAPHIC_ROTATE_270: {
1805             return GraphicTransformType::GRAPHIC_ROTATE_90;
1806         }
1807         case GraphicTransformType::GRAPHIC_FLIP_H_ROT90: {
1808             return GraphicTransformType::GRAPHIC_FLIP_V_ROT90;
1809         }
1810         case GraphicTransformType::GRAPHIC_FLIP_H_ROT270: {
1811             return GraphicTransformType::GRAPHIC_FLIP_V_ROT270;
1812         }
1813         case GraphicTransformType::GRAPHIC_FLIP_V_ROT90: {
1814             return GraphicTransformType::GRAPHIC_FLIP_H_ROT90;
1815         }
1816         case GraphicTransformType::GRAPHIC_FLIP_V_ROT270: {
1817             return GraphicTransformType::GRAPHIC_FLIP_H_ROT270;
1818         }
1819         default: {
1820             return transform;
1821         }
1822     }
1823 }
1824 
RotateEnumToInt(ScreenRotation rotation)1825 int RSBaseRenderUtil::RotateEnumToInt(ScreenRotation rotation)
1826 {
1827     static const std::map<ScreenRotation, int> screenRotationEnumToIntMap = {
1828         {ScreenRotation::ROTATION_0, 0}, {ScreenRotation::ROTATION_90, 90},
1829         {ScreenRotation::ROTATION_180, 180}, {ScreenRotation::ROTATION_270, 270}};
1830     auto iter = screenRotationEnumToIntMap.find(rotation);
1831     return iter != screenRotationEnumToIntMap.end() ? iter->second : 0;
1832 }
1833 
RotateEnumToInt(GraphicTransformType rotation)1834 int RSBaseRenderUtil::RotateEnumToInt(GraphicTransformType rotation)
1835 {
1836     static const std::map<GraphicTransformType, int> transformTypeEnumToIntMap = {
1837         {GraphicTransformType::GRAPHIC_ROTATE_NONE, 0}, {GraphicTransformType::GRAPHIC_ROTATE_90, 90},
1838         {GraphicTransformType::GRAPHIC_ROTATE_180, 180}, {GraphicTransformType::GRAPHIC_ROTATE_270, 270}};
1839     auto iter = transformTypeEnumToIntMap.find(rotation);
1840     return iter != transformTypeEnumToIntMap.end() ? iter->second : 0;
1841 }
1842 
RotateEnumToInt(int angle,GraphicTransformType flip)1843 GraphicTransformType RSBaseRenderUtil::RotateEnumToInt(int angle, GraphicTransformType flip)
1844 {
1845     static const std::map<int, GraphicTransformType> intToEnumMap = {
1846         {0, GraphicTransformType::GRAPHIC_ROTATE_NONE}, {90, GraphicTransformType::GRAPHIC_ROTATE_270},
1847         {180, GraphicTransformType::GRAPHIC_ROTATE_180}, {270, GraphicTransformType::GRAPHIC_ROTATE_90}};
1848     static const std::map<std::pair<int, GraphicTransformType>, GraphicTransformType> pairToEnumMap = {
1849         {{0, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_H},
1850         {{0, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_V},
1851         {{90, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_V_ROT90},
1852         {{90, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_H_ROT90},
1853         {{180, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_V},
1854         {{180, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_H},
1855         {{270, GraphicTransformType::GRAPHIC_FLIP_H}, GraphicTransformType::GRAPHIC_FLIP_H_ROT90},
1856         {{270, GraphicTransformType::GRAPHIC_FLIP_V}, GraphicTransformType::GRAPHIC_FLIP_V_ROT90},
1857     };
1858 
1859     if (flip != GraphicTransformType::GRAPHIC_FLIP_H && flip != GraphicTransformType::GRAPHIC_FLIP_V) {
1860         auto iter = intToEnumMap.find(angle);
1861         return iter != intToEnumMap.end() ? iter->second : GraphicTransformType::GRAPHIC_ROTATE_NONE;
1862     } else {
1863         auto iter = pairToEnumMap.find({angle, flip});
1864         return iter != pairToEnumMap.end() ? iter->second : GraphicTransformType::GRAPHIC_ROTATE_NONE;
1865     }
1866 }
1867 
GetAccumulatedBufferCount()1868 int RSBaseRenderUtil::GetAccumulatedBufferCount()
1869 {
1870     return std::max(acquiredBufferCount_ -  1, 0);
1871 }
1872 
IncAcquiredBufferCount()1873 void RSBaseRenderUtil::IncAcquiredBufferCount()
1874 {
1875     ++acquiredBufferCount_;
1876     RS_TRACE_NAME_FMT("Inc Acq BufferCount %d", acquiredBufferCount_.load());
1877 }
1878 
DecAcquiredBufferCount()1879 void RSBaseRenderUtil::DecAcquiredBufferCount()
1880 {
1881     --acquiredBufferCount_;
1882     RS_TRACE_NAME_FMT("Dec Acq BufferCount %d", acquiredBufferCount_.load());
1883 }
1884 
GetLastSendingPid()1885 pid_t RSBaseRenderUtil::GetLastSendingPid()
1886 {
1887     return lastSendingPid_;
1888 }
1889 
1890 } // namespace Rosen
1891 } // namespace OHOS
1892