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