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 linoff = srcY * stride + srcX * bpp;
68
69 // setup plane alpha
70 if ((mBlending == HWC_BLENDING_PREMULT) && (mPlaneAlpha == 0)) {
71 planeAlpha = mPlaneAlpha | 0x80000000;
72 } else {
73 // disable plane alpha to offload HW
74 planeAlpha = 0;
75 }
76
77 // unlikely happen, but still we need make sure linoff is valid
78 if (linoff > (stride * mapper.getHeight())) {
79 ETRACE("invalid source crop");
80 return false;
81 }
82
83 // update context
84 mContext.type = DC_SPRITE_PLANE;
85 mContext.ctx.sp_ctx.index = mIndex;
86 mContext.ctx.sp_ctx.pipe = mDevice;
87 // none blending and BRGA format layer,set format to BGRX8888
88 if (mBlending == HWC_BLENDING_NONE && spriteFormat == PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888)
89 mContext.ctx.sp_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRX8888
90 | 0x80000000;
91 else
92 mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000;
93 mContext.ctx.sp_ctx.linoff = linoff;
94 mContext.ctx.sp_ctx.stride = stride;
95 mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12;
96 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
97 mContext.ctx.sp_ctx.size =
98 ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff);
99 mContext.ctx.sp_ctx.contalpa = planeAlpha;
100 mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL;
101 mContext.gtt_key = (uint64_t)mapper.getCpuAddress(0);
102
103 VTRACE("cntr = %#x, linoff = %#x, stride = %#x,"
104 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x",
105 mContext.ctx.sp_ctx.cntr,
106 mContext.ctx.sp_ctx.linoff,
107 mContext.ctx.sp_ctx.stride,
108 mContext.ctx.sp_ctx.surf,
109 mContext.ctx.sp_ctx.pos,
110 mContext.ctx.sp_ctx.size,
111 mContext.ctx.sp_ctx.contalpa);
112 return true;
113 }
114
getContext() const115 void* TngSpritePlane::getContext() const
116 {
117 CTRACE();
118 return (void *)&mContext;
119 }
120
enablePlane(bool enabled)121 bool TngSpritePlane::enablePlane(bool enabled)
122 {
123 RETURN_FALSE_IF_NOT_INIT();
124
125 struct drm_psb_register_rw_arg arg;
126 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
127 if (enabled) {
128 arg.plane_enable_mask = 1;
129 } else {
130 arg.plane_disable_mask = 1;
131 }
132 arg.plane.type = DC_SPRITE_PLANE;
133 arg.plane.index = mIndex;
134 arg.plane.ctx = 0;
135
136 // issue ioctl
137 Drm *drm = Hwcomposer::getInstance().getDrm();
138 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
139 if (ret == false) {
140 WTRACE("sprite enabling (%d) failed with error code %d", enabled, ret);
141 return false;
142 }
143
144 Hwcomposer& hwc = Hwcomposer::getInstance();
145 DisplayPlaneManager *pm = hwc.getPlaneManager();
146 void *config = pm->getZOrderConfig();
147 if (config != NULL) {
148 struct intel_dc_plane_zorder *zorder = (struct intel_dc_plane_zorder *)config;
149 zorder->abovePrimary = 0;
150 }
151
152 return true;
153
154 }
155
isDisabled()156 bool TngSpritePlane::isDisabled()
157 {
158 RETURN_FALSE_IF_NOT_INIT();
159
160 struct drm_psb_register_rw_arg arg;
161 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
162
163 if (mType == DisplayPlane::PLANE_SPRITE)
164 arg.plane.type = DC_SPRITE_PLANE;
165 else
166 arg.plane.type = DC_PRIMARY_PLANE;
167
168 arg.get_plane_state_mask = 1;
169 arg.plane.index = mIndex;
170 arg.plane.ctx = 0;
171
172 // issue ioctl
173 Drm *drm = Hwcomposer::getInstance().getDrm();
174 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
175 if (ret == false) {
176 WTRACE("plane state query failed with error code %d", ret);
177 return false;
178 }
179
180 return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
181 }
182
setZOrderConfig(ZOrderConfig & zorderConfig,void * nativeConfig)183 void TngSpritePlane::setZOrderConfig(ZOrderConfig& zorderConfig,
184 void *nativeConfig)
185 {
186 if (!nativeConfig) {
187 ETRACE("Invalid parameter, no native config");
188 return;
189 }
190
191 mAbovePrimary = false;
192
193 int primaryIndex = -1;
194 int spriteIndex = -1;
195 // only consider force bottom when overlay is active
196 for (size_t i = 0; i < zorderConfig.size(); i++) {
197 DisplayPlane *plane = zorderConfig[i]->plane;
198 if (plane->getType() == DisplayPlane::PLANE_PRIMARY)
199 primaryIndex = i;
200 if (plane->getType() == DisplayPlane::PLANE_SPRITE) {
201 spriteIndex = i;
202 }
203 }
204
205 // if has overlay plane which is below primary plane
206 if (spriteIndex > primaryIndex) {
207 mAbovePrimary = true;
208 }
209
210 struct intel_dc_plane_zorder *zorder =
211 (struct intel_dc_plane_zorder *)nativeConfig;
212 zorder->abovePrimary = mAbovePrimary ? 1 : 0;
213 }
214 } // namespace intel
215 } // namespace android
216