1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "hdi_composition_check.h" 17094332d3Sopenharmony_ci#include "display_test.h" 18094332d3Sopenharmony_cinamespace OHOS { 19094332d3Sopenharmony_cinamespace HDI { 20094332d3Sopenharmony_cinamespace Display { 21094332d3Sopenharmony_cinamespace TEST { 22094332d3Sopenharmony_ciusing namespace OHOS::HDI::Display::Composer::V1_1; 23094332d3Sopenharmony_cistatic void GetCheckPoints(Point center, std::vector<Point> &points) 24094332d3Sopenharmony_ci{ 25094332d3Sopenharmony_ci const uint32_t STEP = 3; 26094332d3Sopenharmony_ci points.push_back(center); 27094332d3Sopenharmony_ci points.push_back({center.x + STEP, center.y}); 28094332d3Sopenharmony_ci points.push_back({center.x + STEP, center.y + STEP}); 29094332d3Sopenharmony_ci points.push_back({center.x + STEP, center.y - STEP}); 30094332d3Sopenharmony_ci points.push_back({center.x, center.y + STEP}); 31094332d3Sopenharmony_ci points.push_back({center.x - STEP, center.y}); 32094332d3Sopenharmony_ci points.push_back({center.x - STEP, center.y - STEP}); 33094332d3Sopenharmony_ci points.push_back({center.x - STEP, center.y + STEP}); 34094332d3Sopenharmony_ci points.push_back({center.x, center.y - STEP}); 35094332d3Sopenharmony_ci} 36094332d3Sopenharmony_ci// simple hande the alpha it may not compatible with all scenarios 37094332d3Sopenharmony_cistatic void SimpleHandleAlpha(const LayerSettings& layers, uint32_t& color) 38094332d3Sopenharmony_ci{ 39094332d3Sopenharmony_ci const float INV = 1.0f / 255.0f; 40094332d3Sopenharmony_ci const uint32_t WHITE_TRANSPARENT = 0xffffff00; 41094332d3Sopenharmony_ci const int32_t ALPHA = 0xff; 42094332d3Sopenharmony_ci if (layers.alpha != -1) { 43094332d3Sopenharmony_ci switch (layers.blendType) { 44094332d3Sopenharmony_ci case BLEND_SRC: 45094332d3Sopenharmony_ci color = (color & WHITE_TRANSPARENT) | (layers.alpha & ALPHA); // get the alpha 46094332d3Sopenharmony_ci break; 47094332d3Sopenharmony_ci case BLEND_SRCOVER: 48094332d3Sopenharmony_ci color = color * (layers.alpha * INV); 49094332d3Sopenharmony_ci color = (color & WHITE_TRANSPARENT) | (layers.alpha & ALPHA); // get the alpha 50094332d3Sopenharmony_ci break; 51094332d3Sopenharmony_ci default: 52094332d3Sopenharmony_ci break; 53094332d3Sopenharmony_ci } 54094332d3Sopenharmony_ci } 55094332d3Sopenharmony_ci} 56094332d3Sopenharmony_ci 57094332d3Sopenharmony_cistatic std::vector<uint32_t> GetCheckColors(const std::vector<LayerSettings> &layers, const std::vector<Point> &points) 58094332d3Sopenharmony_ci{ 59094332d3Sopenharmony_ci std::vector<uint32_t> colors; 60094332d3Sopenharmony_ci for (auto point : points) { 61094332d3Sopenharmony_ci uint32_t color = 0; 62094332d3Sopenharmony_ci for (uint32_t i = layers.size(); i > 0; i--) { 63094332d3Sopenharmony_ci auto layer = layers[i - 1]; 64094332d3Sopenharmony_ci const IRect& RECT = layer.displayRect; 65094332d3Sopenharmony_ci // check whether the point is inside the rect 66094332d3Sopenharmony_ci if ((point.x >= RECT.x) && (point.x < (RECT.x + RECT.w)) && (point.y >= RECT.y) && 67094332d3Sopenharmony_ci (point.y < (RECT.y + RECT.h))) { 68094332d3Sopenharmony_ci if (layer.compositionType != Composer::V1_0::CompositionType::COMPOSITION_VIDEO) { 69094332d3Sopenharmony_ci color = layer.color; 70094332d3Sopenharmony_ci SimpleHandleAlpha(layer, color); 71094332d3Sopenharmony_ci } 72094332d3Sopenharmony_ci break; 73094332d3Sopenharmony_ci } 74094332d3Sopenharmony_ci } 75094332d3Sopenharmony_ci colors.push_back(color); 76094332d3Sopenharmony_ci } 77094332d3Sopenharmony_ci return colors; 78094332d3Sopenharmony_ci} 79094332d3Sopenharmony_ci 80094332d3Sopenharmony_ciint32_t HdiCompositionCheck::Check(const std::vector<LayerSettings> &layers, 81094332d3Sopenharmony_ci const BufferHandle& clientBuffer, uint32_t checkType) const 82094332d3Sopenharmony_ci{ 83094332d3Sopenharmony_ci int ret = DISPLAY_SUCCESS; 84094332d3Sopenharmony_ci const int MID_POS = 2; 85094332d3Sopenharmony_ci // get the all check point 86094332d3Sopenharmony_ci std::vector<Point> points; 87094332d3Sopenharmony_ci for (auto layer : layers) { 88094332d3Sopenharmony_ci const IRect& RECT = layer.displayRect; 89094332d3Sopenharmony_ci if (checkType == CHECK_VERTEX) { 90094332d3Sopenharmony_ci GetCheckPoints({RECT.x, RECT.y}, points); 91094332d3Sopenharmony_ci GetCheckPoints({RECT.x, RECT.y + RECT.h}, points); 92094332d3Sopenharmony_ci GetCheckPoints({RECT.x + RECT.w, RECT.y}, points); 93094332d3Sopenharmony_ci GetCheckPoints({RECT.x + RECT.w, RECT.y + RECT.h}, points); 94094332d3Sopenharmony_ci } else { 95094332d3Sopenharmony_ci GetCheckPoints({RECT.x + RECT.w / MID_POS, RECT.y + RECT.h / MID_POS}, points); // center point 96094332d3Sopenharmony_ci } 97094332d3Sopenharmony_ci } 98094332d3Sopenharmony_ci 99094332d3Sopenharmony_ci // get all the check color 100094332d3Sopenharmony_ci std::vector<uint32_t> colors = GetCheckColors(layers, points); 101094332d3Sopenharmony_ci DISPLAY_TEST_CHK_RETURN((colors.size() != points.size()), DISPLAY_FAILURE, 102094332d3Sopenharmony_ci DISPLAY_TEST_LOGE("Points and colors don't match")); 103094332d3Sopenharmony_ci for (uint32_t i = 0; i < points.size(); i++) { 104094332d3Sopenharmony_ci if ((points[i].x >= clientBuffer.width) || (points[i].x < 0) || (points[i].y < 0) || 105094332d3Sopenharmony_ci (points[i].y >= clientBuffer.height)) { 106094332d3Sopenharmony_ci continue; 107094332d3Sopenharmony_ci } 108094332d3Sopenharmony_ci ret = CheckPixel(clientBuffer, points[i].x, points[i].y, colors[i]); 109094332d3Sopenharmony_ci if (ret != DISPLAY_SUCCESS) { 110094332d3Sopenharmony_ci DISPLAY_TEST_LOGE("check failed"); 111094332d3Sopenharmony_ci break; 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci } 114094332d3Sopenharmony_ci return ret; 115094332d3Sopenharmony_ci} 116094332d3Sopenharmony_ci} // OHOS 117094332d3Sopenharmony_ci} // HDI 118094332d3Sopenharmony_ci} // Display 119094332d3Sopenharmony_ci} // TEST 120