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 
17 #include <common/utils/HwcTrace.h>
18 #include <Hwcomposer.h>
19 #include <BufferManager.h>
20 #include <ips/anniedale/AnnCursorPlane.h>
21 #include <ips/tangier/TngGrallocBuffer.h>
22 #include <hal_public.h>
23 
24 namespace android {
25 namespace intel {
26 
AnnCursorPlane(int index,int disp)27 AnnCursorPlane::AnnCursorPlane(int index, int disp)
28     : DisplayPlane(index, PLANE_CURSOR, disp)
29 {
30     CTRACE();
31     memset(&mContext, 0, sizeof(mContext));
32     memset(&mCrop, 0, sizeof(mCrop));
33 }
34 
~AnnCursorPlane()35 AnnCursorPlane::~AnnCursorPlane()
36 {
37     CTRACE();
38 }
39 
enable()40 bool AnnCursorPlane::enable()
41 {
42     return enablePlane(true);
43 }
44 
disable()45 bool AnnCursorPlane::disable()
46 {
47     return enablePlane(false);
48 }
49 
reset()50 bool AnnCursorPlane::reset()
51 {
52     // clear mCrop once reset
53     memset(&mCrop, 0, sizeof(mCrop));
54     return true;
55 }
56 
getContext() const57 void* AnnCursorPlane::getContext() const
58 {
59     CTRACE();
60     return (void *)&mContext;
61 }
62 
setZOrderConfig(ZOrderConfig & config,void * nativeConfig)63 void AnnCursorPlane::setZOrderConfig(ZOrderConfig& config, void *nativeConfig)
64 {
65     (void) config;
66     (void) nativeConfig;
67 
68     CTRACE();
69 }
70 
setDataBuffer(uint32_t handle)71 bool AnnCursorPlane::setDataBuffer(uint32_t handle)
72 {
73     bool ret;
74 
75     if (!handle) {
76         ELOGTRACE("handle is NULL");
77         return false;
78     }
79 
80     ret = DisplayPlane::setDataBuffer(handle);
81     if (ret == false) {
82         ELOGTRACE("failed to set data buffer");
83         return ret;
84     }
85 
86     return true;
87 }
88 
setDataBuffer(BufferMapper & mapper)89 bool AnnCursorPlane::setDataBuffer(BufferMapper& mapper)
90 {
91     int w = mapper.getWidth();
92     int h = mapper.getHeight();
93     int cursorSize = 0;
94 
95     CTRACE();
96 
97     // setup plane position
98     int dstX = mPosition.x;
99     int dstY = mPosition.y;
100     int dstW = mPosition.w;
101     int dstH = mPosition.h;
102 
103     if (h < w) {
104         cursorSize = h;
105     } else {
106         cursorSize = w;
107     }
108 
109     uint32_t cntr = 0;
110     if (64 <= cursorSize && cursorSize < 128) {
111         cursorSize = 64;
112         cntr = 0x7;
113     } else if (128 <= cursorSize && cursorSize < 256) {
114         cursorSize = 128;
115         cntr = 0x2;
116     } else {
117         cursorSize = 256;
118         cntr = 0x3;
119     }
120 
121     if (mapper.getFormat() == HAL_PIXEL_FORMAT_RGBA_8888) {
122         cntr |= 1 << 5;
123     } else if (mapper.getFormat() == HAL_PIXEL_FORMAT_BGRA_8888) {
124         // swap color from BGRA to RGBA - alpha is MSB
125         uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0));
126         uint8_t *srcPixel;
127         uint32_t stride = mapper.getStride().rgb.stride;
128         uint8_t temp;
129         if (!p) {
130             return false;
131         }
132 
133         for (int i = 0; i < cursorSize; i++) {
134             for (int j = 0; j < cursorSize; j++) {
135                 srcPixel = p + i*stride + j*4;
136                 temp = srcPixel[0];
137                 srcPixel[0] = srcPixel[2];
138                 srcPixel[2] = temp;
139             }
140         }
141         cntr |= 1 << 5;
142     } else {
143         ELOGTRACE("invalid color format");
144         return false;
145     }
146 
147     // TODO: clean spare mem to be 0 in gralloc instead
148     uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0));
149     uint8_t *srcPixel;
150     uint32_t stride = mapper.getStride().rgb.stride;
151     uint8_t temp;
152     if (!p) {
153         return false;
154     }
155 
156     if (mCrop.w == 0 && mCrop.h == 0) {
157         mCrop = mSrcCrop;
158         for (int i = 0; i < cursorSize; i++) {
159             for (int j = 0; j < cursorSize; j++) {
160                 srcPixel = p + i*stride + j*4;
161                 temp = srcPixel[0];
162                 if (i >= mCrop.h || j >= mCrop.w) {
163                     if (srcPixel[0] == 0 &&
164                         srcPixel[3] == 0xff)
165                         srcPixel[3] = 0;
166                 }
167             }
168         }
169     }
170 
171     // update context
172     mContext.type = DC_CURSOR_PLANE;
173     mContext.ctx.cs_ctx.index = mIndex;
174     mContext.ctx.cs_ctx.pipe = mDevice;
175     mContext.ctx.cs_ctx.cntr = cntr;
176     mContext.ctx.cs_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
177 
178     mContext.ctx.cs_ctx.pos = 0;
179     if (dstX < 0) {
180         mContext.ctx.cs_ctx.pos |= 1 << 15;
181         dstX = -dstX;
182     }
183     if (dstY < 0) {
184         mContext.ctx.cs_ctx.pos |= 1 << 31;
185         dstY = -dstY;
186     }
187     mContext.ctx.cs_ctx.pos |= (dstY & 0xfff) << 16 | (dstX & 0xfff);
188     return true;
189 }
190 
enablePlane(bool enabled)191 bool AnnCursorPlane::enablePlane(bool enabled)
192 {
193     RETURN_FALSE_IF_NOT_INIT();
194 
195     struct drm_psb_register_rw_arg arg;
196     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
197     if (enabled) {
198         arg.plane_enable_mask = 1;
199     } else {
200         arg.plane_disable_mask = 1;
201     }
202 
203     arg.plane.type = DC_CURSOR_PLANE;
204     arg.plane.index = mIndex;
205     arg.plane.ctx = 0;
206 
207     // issue ioctl
208     Drm *drm = Hwcomposer::getInstance().getDrm();
209     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
210     if (ret == false) {
211         WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret);
212         return false;
213     }
214 
215     return true;
216 }
217 
isDisabled()218 bool AnnCursorPlane::isDisabled()
219 {
220     RETURN_FALSE_IF_NOT_INIT();
221 
222     struct drm_psb_register_rw_arg arg;
223     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
224 
225     arg.plane.type = DC_CURSOR_PLANE;
226     arg.get_plane_state_mask = 1;
227     arg.plane.index = mIndex;
228     arg.plane.ctx = 0;
229 
230     // issue ioctl
231     Drm *drm = Hwcomposer::getInstance().getDrm();
232     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
233     if (ret == false) {
234         WLOGTRACE("plane state query failed with error code %d", ret);
235         return false;
236     }
237 
238     return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
239 }
240 
postFlip()241 void AnnCursorPlane::postFlip()
242 {
243     // prevent mUpdateMasks from being reset
244     // skipping flip may cause flicking
245 }
246 
247 } // namespace intel
248 } // namespace android
249