• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Samsung Electronics Co.,LTD.
3  * Copyright (C) 2016 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <algorithm>
19 
20 #include <log/log.h>
21 
22 #include <hardware/exynos/acryl.h>
23 
24 #include "acrylic_internal.h"
25 
Acrylic(const HW2DCapability & capability)26 Acrylic::Acrylic(const HW2DCapability &capability)
27     : mCapability(capability), mHasBackgroundColor(false),
28       mMaxTargetLuminance(100), mMinTargetLuminance(0), mTargetDisplayInfo(nullptr),
29       mCanvas(this, AcrylicCanvas::CANVAS_TARGET)
30 {
31     ALOGD_TEST("Created a new Acrylic on %p", this);
32 }
33 
~Acrylic()34 Acrylic::~Acrylic()
35 {
36     mCanvas.disconnectLayer();
37 
38     for (auto layer: mLayers) {
39         layer->disconnectLayer();
40         removeTransitData(layer);
41     }
42 
43     ALOGD_TEST("Destroyed Acrylic on %p", this);
44 }
45 
createLayer()46 AcrylicLayer *Acrylic::createLayer()
47 {
48     if (mLayers.size() >= getCapabilities().maxLayerCount()) {
49         ALOGE("Full of composit layer: current %zu, max %u",
50                 mLayers.size() , getCapabilities().maxLayerCount());
51         return NULL;
52     }
53 
54     auto *layer = new AcrylicLayer(this);
55     if (!layer) {
56         ALOGE("Failed to create a new compositing layer");
57         return NULL;
58     }
59 
60     mLayers.push_back(layer);
61 
62     ALOGD_TEST("A new Acrylic layer is created. Total %zd layers", mLayers.size());
63 
64     return layer;
65 }
66 
removeLayer(AcrylicLayer * layer)67 void Acrylic::removeLayer(AcrylicLayer *layer)
68 {
69     auto it = find(std::begin(mLayers), std::end(mLayers), layer);
70 
71     if (it == std::end(mLayers)) {
72         ALOGE("Deleting an unregistered layer");
73     } else {
74         removeTransitData(*it);
75         mLayers.erase(it);
76     }
77 }
78 
prioritize(int priority)79 int Acrylic::prioritize(int priority)
80 {
81     if ((priority < -1) || (priority > 15)) {
82         ALOGE("Invalid priority %d", priority);
83         return -1;
84     }
85 
86     return 0;
87 }
88 
requestPerformanceQoS(AcrylicPerformanceRequest __unused * request)89 bool Acrylic::requestPerformanceQoS(AcrylicPerformanceRequest __unused *request)
90 {
91     return true;
92 }
93 
setHDRToneMapCoefficients(uint32_t __unused * matrix[2],int __unused num_elements)94 bool Acrylic::setHDRToneMapCoefficients(uint32_t __unused *matrix[2], int __unused num_elements)
95 {
96     return true;
97 }
98 
validateAllLayers()99 bool Acrylic::validateAllLayers()
100 {
101     const HW2DCapability &cap = getCapabilities();
102 
103     if (!mCanvas.isSettingOkay()) {
104         ALOGE("Incomplete settting (flags: %#x) on the target layer",
105               mCanvas.getSettingFlags());
106         return false;
107     }
108 
109     if ((mCanvas.isCompressed() || mCanvas.isCompressedWideblk()) &&
110         !cap.isFeatureSupported(HW2DCapability::FEATURE_AFBC_ENCODE)) {
111         ALOGE("AFBC encoding is not supported");
112         return false;
113     }
114 
115     if (mCanvas.isUOrder() && !cap.isFeatureSupported(HW2DCapability::FEATURE_UORDER_WRITE)) {
116         ALOGE("Writing in U-Order is not supported");
117         return false;
118     }
119 
120     bool prot = false;
121     hw2d_rect_t rect;
122     hw2d_coord_t xy = mCanvas.getImageDimension();
123 
124     for (auto layer: mLayers) {
125         if (!layer->isSettingOkay()) {
126             ALOGE("Incomplete settting (flags: %#x) on a layer of %zu layers",
127                   layer->getSettingFlags(), mLayers.size());
128             return false;
129         }
130 
131         if ((layer->isCompressed() || layer->isCompressedWideblk()) &&
132             !cap.isFeatureSupported(HW2DCapability::FEATURE_AFBC_DECODE)) {
133             ALOGE("AFBC decoding is not supported");
134             return false;
135         }
136 
137         if (layer->isUOrder() && !cap.isFeatureSupported(HW2DCapability::FEATURE_UORDER_READ)) {
138             ALOGE("Reading a texture in U-Order is not supported");
139             return false;
140         }
141 
142         if ((layer->getPlaneAlpha() != 255) && !cap.isFeatureSupported(HW2DCapability::FEATURE_PLANE_ALPHA)) {
143             ALOGE("Plane alpha is not supported but given %u for plane alpha", layer->getPlaneAlpha());
144             return false;
145         }
146 
147         rect = layer->getTargetRect();
148         if (area_is_zero(rect)) {
149             // If no target area is specified to a source layer,
150             // the entire region of the target image becomes the target area.
151             // Then, check the scaling capability
152             hw2d_rect_t ir = layer->getImageRect();
153             if (!!(layer->getCompositAttr() & AcrylicLayer::ATTR_NORESAMPLING)) {
154                 if (!cap.supportedResizing(ir.size, xy, layer->getTransform())) {
155                     ALOGE("Unsupported resizing from %dx%d@(%d,%d) --> Target %dx%d with transform %d",
156                           ir.size.hori, ir.size.vert, ir.pos.hori, ir.pos.vert,
157                           xy.hori, xy.vert, layer->getTransform());
158                     return false;
159                 }
160             } else {
161                 if (!cap.supportedResampling(ir.size, xy, layer->getTransform())) {
162                     ALOGE("Unsupported scaling from %dx%d@(%d,%d) --> Target %dx%d with transform %d",
163                           ir.size.hori, ir.size.vert, ir.pos.hori, ir.pos.vert,
164                           xy.hori, xy.vert, layer->getTransform());
165                     return false;
166                 }
167             }
168         } else if (rect > xy) {
169             ALOGE("Target area %dx%d@(%d,%d) of a layer of %zu layers is out of bound (%dx%d)",
170                     rect.size.hori, rect.size.vert, rect.pos.hori, rect.pos.vert,
171                     mLayers.size(), xy.hori, xy.vert);
172             return false;
173         }
174 
175         prot = prot || layer->isProtected();
176     }
177 
178     if (prot && !mCanvas.isProtected()) {
179         ALOGE("Target image is not protected while a source layer is protected");
180         return false;
181     }
182 
183     return true;
184 }
185 
sortLayers()186 void Acrylic::sortLayers()
187 {
188     std::sort(std::begin(mLayers), std::end(mLayers), [] (auto l1, auto l2) { return l1->getZOrder() < l2->getZOrder(); });
189 }
190