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 
101     if (h < w) {
102         cursorSize = h;
103     } else {
104         cursorSize = w;
105     }
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         ELOGTRACE("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     if (!p) {
150         return false;
151     }
152 
153     if (mCrop.w == 0 && mCrop.h == 0) {
154         mCrop = mSrcCrop;
155         for (int i = 0; i < cursorSize; i++) {
156             for (int j = 0; j < cursorSize; j++) {
157                 srcPixel = p + i*stride + j*4;
158                 if (i >= mCrop.h || j >= mCrop.w) {
159                     if (srcPixel[0] == 0 &&
160                         srcPixel[3] == 0xff)
161                         srcPixel[3] = 0;
162                 }
163             }
164         }
165     }
166 
167     // update context
168     mContext.type = DC_CURSOR_PLANE;
169     mContext.ctx.cs_ctx.index = mIndex;
170     mContext.ctx.cs_ctx.pipe = mDevice;
171     mContext.ctx.cs_ctx.cntr = cntr;
172     mContext.ctx.cs_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
173 
174     mContext.ctx.cs_ctx.pos = 0;
175     if (dstX < 0) {
176         mContext.ctx.cs_ctx.pos |= 1 << 15;
177         dstX = -dstX;
178     }
179     if (dstY < 0) {
180         mContext.ctx.cs_ctx.pos |= 1 << 31;
181         dstY = -dstY;
182     }
183     mContext.ctx.cs_ctx.pos |= (dstY & 0xfff) << 16 | (dstX & 0xfff);
184     return true;
185 }
186 
enablePlane(bool enabled)187 bool AnnCursorPlane::enablePlane(bool enabled)
188 {
189     RETURN_FALSE_IF_NOT_INIT();
190 
191     struct drm_psb_register_rw_arg arg;
192     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
193     if (enabled) {
194         arg.plane_enable_mask = 1;
195     } else {
196         arg.plane_disable_mask = 1;
197     }
198 
199     arg.plane.type = DC_CURSOR_PLANE;
200     arg.plane.index = mIndex;
201     arg.plane.ctx = 0;
202 
203     // issue ioctl
204     Drm *drm = Hwcomposer::getInstance().getDrm();
205     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
206     if (ret == false) {
207         WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret);
208         return false;
209     }
210 
211     return true;
212 }
213 
isDisabled()214 bool AnnCursorPlane::isDisabled()
215 {
216     RETURN_FALSE_IF_NOT_INIT();
217 
218     struct drm_psb_register_rw_arg arg;
219     memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
220 
221     arg.plane.type = DC_CURSOR_PLANE;
222     arg.get_plane_state_mask = 1;
223     arg.plane.index = mIndex;
224     arg.plane.ctx = 0;
225 
226     // issue ioctl
227     Drm *drm = Hwcomposer::getInstance().getDrm();
228     bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
229     if (ret == false) {
230         WLOGTRACE("plane state query failed with error code %d", ret);
231         return false;
232     }
233 
234     return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
235 }
236 
postFlip()237 void AnnCursorPlane::postFlip()
238 {
239     // prevent mUpdateMasks from being reset
240     // skipping flip may cause flicking
241 }
242 
243 } // namespace intel
244 } // namespace android
245