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 #if ENABLE_ROTATION_180
103     dstX = mModeInfo.hdisplay - dstX - cursorSize;
104     dstY = mModeInfo.vdisplay - dstY - cursorSize;
105 #endif
106 
107     uint32_t cntr = 0;
108     if (64 <= cursorSize && cursorSize < 128) {
109         cursorSize = 64;
110         cntr = 0x7;
111     } else if (128 <= cursorSize && cursorSize < 256) {
112         cursorSize = 128;
113         cntr = 0x2;
114     } else {
115         cursorSize = 256;
116         cntr = 0x3;
117     }
118 
119     if (mapper.getFormat() == HAL_PIXEL_FORMAT_RGBA_8888) {
120         cntr |= 1 << 5;
121     } else if (mapper.getFormat() == HAL_PIXEL_FORMAT_BGRA_8888) {
122         // swap color from BGRA to RGBA - alpha is MSB
123         uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0));
124         uint8_t *srcPixel;
125         uint32_t stride = mapper.getStride().rgb.stride;
126         uint8_t temp;
127         if (!p) {
128             return false;
129         }
130 
131         for (int i = 0; i < cursorSize; i++) {
132             for (int j = 0; j < cursorSize; j++) {
133                 srcPixel = p + i*stride + j*4;
134                 temp = srcPixel[0];
135                 srcPixel[0] = srcPixel[2];
136                 srcPixel[2] = temp;
137             }
138         }
139         cntr |= 1 << 5;
140     } else {
141         ETRACE("invalid color format");
142         return false;
143     }
144 
145     // TODO: clean spare mem to be 0 in gralloc instead
146     uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0));
147     uint8_t *srcPixel;
148     uint32_t stride = mapper.getStride().rgb.stride;
149     uint8_t temp;
150     if (!p) {
151         return false;
152     }
153 
154     if (mCrop.w == 0 && mCrop.h == 0) {
155         mCrop = mSrcCrop;
156         for (int i = 0; i < cursorSize; i++) {
157             for (int j = 0; j < cursorSize; j++) {
158                 srcPixel = p + i*stride + j*4;
159                 temp = srcPixel[0];
160                 if (i >= mCrop.h || j >= mCrop.w) {
161                     if (srcPixel[0] == 0 &&
162                         srcPixel[3] == 0xff)
163                         srcPixel[3] = 0;
164                 }
165             }
166         }
167     }
168 
169     // update context
170     mContext.type = DC_CURSOR_PLANE;
171     mContext.ctx.cs_ctx.index = mIndex;
172     mContext.ctx.cs_ctx.pipe = mDevice;
173     mContext.ctx.cs_ctx.cntr = cntr | (mIndex << 28);
174     mContext.ctx.cs_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
175 
176     mContext.ctx.cs_ctx.pos = 0;
177     if (dstX < 0) {
178         mContext.ctx.cs_ctx.pos |= 1 << 15;
179         dstX = -dstX;
180     }
181     if (dstY < 0) {
182         mContext.ctx.cs_ctx.pos |= 1 << 31;
183         dstY = -dstY;
184     }
185     mContext.ctx.cs_ctx.pos |= (dstY & 0xfff) << 16 | (dstX & 0xfff);
186     return true;
187 }
188 
enablePlane(bool enabled)189 bool TngCursorPlane::enablePlane(bool enabled)
190 {
191     RETURN_FALSE_IF_NOT_INIT();
192 
193     struct drm_psb_register_rw_arg arg;
194     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
195     if (enabled) {
196         arg.plane_enable_mask = 1;
197     } else {
198         arg.plane_disable_mask = 1;
199     }
200 
201     arg.plane.type = DC_CURSOR_PLANE;
202     arg.plane.index = mIndex;
203     arg.plane.ctx = 0;
204 
205     // issue ioctl
206     Drm *drm = Hwcomposer::getInstance().getDrm();
207     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
208     if (ret == false) {
209         WTRACE("plane enabling (%d) failed with error code %d", enabled, ret);
210         return false;
211     }
212 
213     return true;
214 }
215 
isDisabled()216 bool TngCursorPlane::isDisabled()
217 {
218     RETURN_FALSE_IF_NOT_INIT();
219 
220     struct drm_psb_register_rw_arg arg;
221     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
222 
223     arg.plane.type = DC_CURSOR_PLANE;
224     arg.get_plane_state_mask = 1;
225     arg.plane.index = mIndex;
226     arg.plane.ctx = 0;
227 
228     // issue ioctl
229     Drm *drm = Hwcomposer::getInstance().getDrm();
230     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
231     if (ret == false) {
232         WTRACE("plane state query failed with error code %d", ret);
233         return false;
234     }
235 
236 	return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
237     //return arg.plane.ctx == 0; //implement this PSB_DC_PLANE_DISABLED similar in imin_legacy
238 
239 	return true;
240 }
241 
postFlip()242 void TngCursorPlane::postFlip()
243 {
244     // prevent mUpdateMasks from being reset
245     // skipping flip may cause flicking
246 }
247 
248 } // namespace intel
249 } // namespace android
250