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