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 ¶ms, 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 ¶m)
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