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