1 /*
2 // Copyright (c) 2014 Intel Corporation 
3 //
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 #include <HwcTrace.h>
17 #include <tangier/TngPlaneManager.h>
18 #include <tangier/TngPrimaryPlane.h>
19 #include <tangier/TngSpritePlane.h>
20 #include <tangier/TngOverlayPlane.h>
21 #include <tangier/TngCursorPlane.h>
22 
23 namespace android {
24 namespace intel {
25 
TngPlaneManager()26 TngPlaneManager::TngPlaneManager()
27     : DisplayPlaneManager()
28 {
29     memset(&mZorder, 0, sizeof(mZorder));
30 }
31 
~TngPlaneManager()32 TngPlaneManager::~TngPlaneManager()
33 {
34 }
35 
initialize()36 bool TngPlaneManager::initialize()
37 {
38     mSpritePlaneCount = 1;  // Sprite D
39     mOverlayPlaneCount = 0;  // Skip overlay A & C by setting count to 0
40     mPrimaryPlaneCount = 3;  // Primary A, B, C
41     mCursorPlaneCount = 3;
42 
43     return DisplayPlaneManager::initialize();
44 }
45 
deinitialize()46 void TngPlaneManager::deinitialize()
47 {
48     DisplayPlaneManager::deinitialize();
49 }
50 
allocPlane(int index,int type)51 DisplayPlane* TngPlaneManager::allocPlane(int index, int type)
52 {
53     DisplayPlane *plane = 0;
54 
55     switch (type) {
56     case DisplayPlane::PLANE_PRIMARY:
57         plane = new TngPrimaryPlane(index, index);
58         break;
59     case DisplayPlane::PLANE_SPRITE:
60         plane = new TngSpritePlane(index, 0);
61         break;
62     case DisplayPlane::PLANE_OVERLAY:
63         plane = new TngOverlayPlane(index, 0);
64         break;
65     case DisplayPlane::PLANE_CURSOR:
66         plane = new TngCursorPlane(index, index /*disp */);
67         break;
68     default:
69         ETRACE("unsupported type %d", type);
70         break;
71     }
72     if (plane && !plane->initialize(DisplayPlane::MIN_DATA_BUFFER_COUNT)) {
73         ETRACE("failed to initialize plane.");
74         DEINIT_AND_DELETE_OBJ(plane);
75     }
76 
77     return plane;
78 }
79 
isValidZOrder(int dsp,ZOrderConfig & config)80 bool TngPlaneManager::isValidZOrder(int dsp, ZOrderConfig& config)
81 {
82     // check whether it's a supported z order config
83     int firstRGB = -1;
84     int lastRGB = -1;
85     int firstOverlay = -1;
86     int lastOverlay = -1;
87 
88     for (int i = 0; i < (int)config.size(); i++) {
89         const ZOrderLayer *layer = config[i];
90         switch (layer->planeType) {
91         case DisplayPlane::PLANE_PRIMARY:
92         case DisplayPlane::PLANE_SPRITE:
93             if (firstRGB == -1) {
94                 firstRGB = i;
95                 lastRGB = i;
96             } else {
97                 lastRGB = i;
98             }
99             break;
100         case DisplayPlane::PLANE_OVERLAY:
101         case DisplayPlane::PLANE_CURSOR:
102             if (firstOverlay == -1) {
103                 firstOverlay = i;
104                 lastOverlay = i;
105             } else {
106                 lastOverlay = i;
107             }
108             break;
109         }
110     }
111 
112     if ((lastRGB < firstOverlay) || (firstRGB > lastOverlay)) {
113         return true;
114     } else {
115         VTRACE("invalid z order config. rgb (%d, %d) yuv (%d, %d)",
116                firstRGB, lastRGB, firstOverlay, lastOverlay);
117         return false;
118     }
119 }
120 
assignPlanes(int dsp,ZOrderConfig & config)121 bool TngPlaneManager::assignPlanes(int dsp, ZOrderConfig& config)
122 {
123     // probe if plane is available
124     int size = (int)config.size();
125     for (int i = 0; i < size; i++) {
126         const ZOrderLayer *layer = config.itemAt(i);
127         if (!getFreePlanes(dsp, layer->planeType)) {
128             DTRACE("no plane available for dsp %d, type %d", dsp, layer->planeType);
129             return false;
130         }
131     }
132 
133     if (config.size() == 1 && config[0]->planeType == DisplayPlane::PLANE_SPRITE) {
134         config[0]->planeType == DisplayPlane::PLANE_PRIMARY;
135     }
136 
137     // allocate planes
138     for (int i = 0; i < size; i++) {
139         ZOrderLayer *layer = config.itemAt(i);
140         layer->plane = getPlaneHelper(dsp, layer->planeType);
141         if (layer->plane == NULL) {
142             // should never happen!!
143             ETRACE("failed to assign plane for type %d", layer->planeType);
144             return false;
145         }
146         // sequence !!!!! enabling plane before setting zorder
147         // see TngSpritePlane::enablePlane implementation!!!!
148         layer->plane->enable();
149     }
150 
151     // setup Z order
152     for (int i = 0; i < size; i++) {
153         ZOrderLayer *layer = config.itemAt(i);
154         layer->plane->setZOrderConfig(config, &mZorder);
155     }
156 
157     return true;
158 }
159 
getZOrderConfig() const160 void* TngPlaneManager::getZOrderConfig() const
161 {
162     return (void*)&mZorder;
163 }
164 
getPlaneHelper(int dsp,int type)165 DisplayPlane* TngPlaneManager::getPlaneHelper(int dsp, int type)
166 {
167     RETURN_NULL_IF_NOT_INIT();
168 
169     if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) {
170         ETRACE("Invalid display device %d", dsp);
171         return 0;
172     }
173 
174     int index = dsp == IDisplayDevice::DEVICE_PRIMARY ? 0 : 1;
175 
176     if (type == DisplayPlane::PLANE_PRIMARY ||
177         type == DisplayPlane::PLANE_CURSOR) {
178         return getPlane(type, index);
179     } else if (type == DisplayPlane::PLANE_SPRITE) {
180         return getAnyPlane(type);
181     } else if (type == DisplayPlane::PLANE_OVERLAY) {
182         // use overlay A for pipe A and overlay C for pipe B if possible
183         DisplayPlane *plane = getPlane(type, index);
184         if (plane == NULL) {
185             plane = getPlane(type, !index);
186         }
187         return plane;
188     } else {
189         ETRACE("invalid plane type %d", type);
190         return 0;
191     }
192 }
193 
194 } // namespace intel
195 } // namespace android
196 
197