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 #include <HwcTrace.h>
17 #include <Hwcomposer.h>
18 #include <BufferManager.h>
19 #include <tangier/TngSpritePlane.h>
20 #include <common/PixelFormat.h>
21
22 namespace android {
23 namespace intel {
24
TngSpritePlane(int index,int disp)25 TngSpritePlane::TngSpritePlane(int index, int disp)
26 : SpritePlaneBase(index, disp)
27 {
28 CTRACE();
29 memset(&mContext, 0, sizeof(mContext));
30 }
31
~TngSpritePlane()32 TngSpritePlane::~TngSpritePlane()
33 {
34 CTRACE();
35 }
36
setDataBuffer(BufferMapper & mapper)37 bool TngSpritePlane::setDataBuffer(BufferMapper& mapper)
38 {
39 int bpp;
40 int srcX, srcY;
41 int dstX, dstY, dstW, dstH;
42 uint32_t spriteFormat;
43 uint32_t stride;
44 uint32_t linoff;
45 uint32_t planeAlpha;
46
47 CTRACE();
48
49 // setup plane position
50 dstX = mPosition.x;
51 dstY = mPosition.y;
52 dstW = mPosition.w;
53 dstH = mPosition.h;
54
55 checkPosition(dstX, dstY, dstW, dstH);
56
57 // setup plane format
58 if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) {
59 ETRACE("unsupported format %#x", mapper.getFormat());
60 return false;
61 }
62
63 // setup stride and source buffer crop
64 srcX = mapper.getCrop().x;
65 srcY = mapper.getCrop().y;
66 stride = mapper.getStride().rgb.stride;
67 #ifdef ENABLE_ROTATION_180
68 linoff = (mapper.getCrop().h + srcY - 1) * stride + (srcX + mapper.getCrop().w - 1) * bpp;
69 #else
70 linoff = srcY * stride + srcX * bpp;
71 #endif
72
73 // setup plane alpha
74 if ((mBlending == HWC_BLENDING_PREMULT) && (mPlaneAlpha == 0)) {
75 planeAlpha = mPlaneAlpha | 0x80000000;
76 } else {
77 // disable plane alpha to offload HW
78 planeAlpha = 0;
79 }
80
81 // unlikely happen, but still we need make sure linoff is valid
82 if (linoff > (stride * mapper.getHeight())) {
83 ETRACE("invalid source crop");
84 return false;
85 }
86
87 // update context
88 mContext.type = DC_SPRITE_PLANE;
89 mContext.ctx.sp_ctx.index = mIndex;
90 mContext.ctx.sp_ctx.pipe = mDevice;
91 // none blending and BRGA format layer,set format to BGRX8888
92 if (mBlending == HWC_BLENDING_NONE && spriteFormat == PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888)
93 mContext.ctx.sp_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRX8888
94 | 0x80000000;
95 else
96 mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000;
97 mContext.ctx.sp_ctx.linoff = linoff;
98 mContext.ctx.sp_ctx.stride = stride;
99 mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
100 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
101 mContext.ctx.sp_ctx.size =
102 ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff);
103 mContext.ctx.sp_ctx.contalpa = planeAlpha;
104 mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL;
105 mContext.gtt_key = (uint64_t)mapper.getCpuAddress(0);
106 #ifdef ENABLE_ROTATION_180
107 mContext.ctx.sp_ctx.cntr |= 1 << 15;
108 #endif
109 VTRACE("cntr = %#x, linoff = %#x, stride = %#x,"
110 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x",
111 mContext.ctx.sp_ctx.cntr,
112 mContext.ctx.sp_ctx.linoff,
113 mContext.ctx.sp_ctx.stride,
114 mContext.ctx.sp_ctx.surf,
115 mContext.ctx.sp_ctx.pos,
116 mContext.ctx.sp_ctx.size,
117 mContext.ctx.sp_ctx.contalpa);
118 return true;
119 }
120
getContext() const121 void* TngSpritePlane::getContext() const
122 {
123 CTRACE();
124 return (void *)&mContext;
125 }
126
enablePlane(bool enabled)127 bool TngSpritePlane::enablePlane(bool enabled)
128 {
129 RETURN_FALSE_IF_NOT_INIT();
130
131 struct drm_psb_register_rw_arg arg;
132 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
133 if (enabled) {
134 arg.plane_enable_mask = 1;
135 } else {
136 arg.plane_disable_mask = 1;
137 }
138 arg.plane.type = DC_SPRITE_PLANE;
139 arg.plane.index = mIndex;
140 arg.plane.ctx = 0;
141
142 // issue ioctl
143 Drm *drm = Hwcomposer::getInstance().getDrm();
144 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
145 if (ret == false) {
146 WTRACE("sprite enabling (%d) failed with error code %d", enabled, ret);
147 return false;
148 }
149
150 Hwcomposer& hwc = Hwcomposer::getInstance();
151 DisplayPlaneManager *pm = hwc.getPlaneManager();
152 void *config = pm->getZOrderConfig();
153 if (config != NULL) {
154 struct intel_dc_plane_zorder *zorder = (struct intel_dc_plane_zorder *)config;
155 zorder->abovePrimary = 0;
156 }
157
158 return true;
159
160 }
161
isDisabled()162 bool TngSpritePlane::isDisabled()
163 {
164 RETURN_FALSE_IF_NOT_INIT();
165
166 struct drm_psb_register_rw_arg arg;
167 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
168
169 if (mType == DisplayPlane::PLANE_SPRITE)
170 arg.plane.type = DC_SPRITE_PLANE;
171 else
172 arg.plane.type = DC_PRIMARY_PLANE;
173
174 arg.get_plane_state_mask = 1;
175 arg.plane.index = mIndex;
176 arg.plane.ctx = 0;
177
178 // issue ioctl
179 Drm *drm = Hwcomposer::getInstance().getDrm();
180 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
181 if (ret == false) {
182 WTRACE("plane state query failed with error code %d", ret);
183 return false;
184 }
185
186 return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
187 }
188
setZOrderConfig(ZOrderConfig & zorderConfig,void * nativeConfig)189 void TngSpritePlane::setZOrderConfig(ZOrderConfig& zorderConfig,
190 void *nativeConfig)
191 {
192 if (!nativeConfig) {
193 ETRACE("Invalid parameter, no native config");
194 return;
195 }
196
197 mAbovePrimary = false;
198
199 int primaryIndex = -1;
200 int spriteIndex = -1;
201 // only consider force bottom when overlay is active
202 for (size_t i = 0; i < zorderConfig.size(); i++) {
203 DisplayPlane *plane = zorderConfig[i]->plane;
204 if (plane->getType() == DisplayPlane::PLANE_PRIMARY)
205 primaryIndex = i;
206 if (plane->getType() == DisplayPlane::PLANE_SPRITE) {
207 spriteIndex = i;
208 }
209 }
210
211 // if has overlay plane which is below primary plane
212 if (spriteIndex > primaryIndex) {
213 mAbovePrimary = true;
214 }
215
216 struct intel_dc_plane_zorder *zorder =
217 (struct intel_dc_plane_zorder *)nativeConfig;
218 zorder->abovePrimary = mAbovePrimary ? 1 : 0;
219 }
220 } // namespace intel
221 } // namespace android
222