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