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