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