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 <Drm.h>
18 #include <tangier/TngPrimaryPlane.h>
19 #include <tangier/TngGrallocBuffer.h>
20 #include <common/PixelFormat.h>
21
22 namespace android {
23 namespace intel {
24
TngPrimaryPlane(int index,int disp)25 TngPrimaryPlane::TngPrimaryPlane(int index, int disp)
26 : TngSpritePlane(index, disp)
27 {
28 CTRACE();
29 mType = PLANE_PRIMARY;
30 mForceBottom = true;
31 mAbovePrimary = false;
32 }
33
~TngPrimaryPlane()34 TngPrimaryPlane::~TngPrimaryPlane()
35 {
36 CTRACE();
37 }
38
setFramebufferTarget(buffer_handle_t handle)39 void TngPrimaryPlane::setFramebufferTarget(buffer_handle_t handle)
40 {
41 CTRACE();
42
43 // do not need to update the buffer handle
44 if (mCurrentDataBuffer != handle)
45 mUpdateMasks |= PLANE_BUFFER_CHANGED;
46 else
47 mUpdateMasks &= ~PLANE_BUFFER_CHANGED;
48
49 // if no update then do Not need set data buffer
50 if (!mUpdateMasks)
51 return;
52
53 // don't need to map data buffer for primary plane
54 mContext.type = DC_PRIMARY_PLANE;
55 mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL;
56 mContext.ctx.prim_ctx.index = mIndex;
57 mContext.ctx.prim_ctx.pipe = mDevice;
58 mContext.ctx.prim_ctx.stride = align_to((4 * align_to(mPosition.w, 32)), 64);
59 #ifdef ENABLE_ROTATION_180
60 mContext.ctx.prim_ctx.linoff = (mPosition.h - 1) * mContext.ctx.prim_ctx.stride + (mPosition.w - 1)* 4;
61 #else
62 mContext.ctx.prim_ctx.linoff = 0;
63 #endif
64 mContext.ctx.prim_ctx.pos = 0;
65 mContext.ctx.prim_ctx.size =
66 ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff);
67 mContext.ctx.prim_ctx.surf = 0;
68 mContext.ctx.prim_ctx.contalpa = 0;
69
70 mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888;
71 #ifdef ENABLE_ROTATION_180
72 mContext.ctx.prim_ctx.cntr |= 0x80008000;
73 #else
74 mContext.ctx.prim_ctx.cntr |= 0x80000000;
75 #endif
76 mCurrentDataBuffer = handle;
77 }
78
enablePlane(bool enabled)79 bool TngPrimaryPlane::enablePlane(bool enabled)
80 {
81 RETURN_FALSE_IF_NOT_INIT();
82
83 struct drm_psb_register_rw_arg arg;
84 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
85 if (enabled) {
86 arg.plane_enable_mask = 1;
87 } else {
88 arg.plane_disable_mask = 1;
89 }
90 arg.plane.type = DC_PRIMARY_PLANE;
91 arg.plane.index = mIndex;
92 arg.plane.ctx = 0;
93
94 // issue ioctl
95 Drm *drm = Hwcomposer::getInstance().getDrm();
96 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
97 if (ret == false) {
98 WTRACE("primary enabling (%d) failed with error code %d", enabled, ret);
99 return false;
100 }
101
102 return true;
103
104 }
105
setDataBuffer(buffer_handle_t handle)106 bool TngPrimaryPlane::setDataBuffer(buffer_handle_t handle)
107 {
108 if (!handle) {
109 setFramebufferTarget(handle);
110 return true;
111 }
112
113 TngGrallocBuffer tmpBuf(handle);
114 uint32_t usage;
115 bool ret;
116
117 ATRACE("handle = %#x", handle);
118
119 usage = tmpBuf.getUsage();
120 if (GRALLOC_USAGE_HW_FB & usage) {
121 setFramebufferTarget(handle);
122 return true;
123 }
124
125 // use primary as a sprite
126 ret = DisplayPlane::setDataBuffer(handle);
127 if (ret == false) {
128 ETRACE("failed to set data buffer");
129 return ret;
130 }
131
132 mContext.type = DC_PRIMARY_PLANE;
133 return true;
134 }
135
setZOrderConfig(ZOrderConfig & zorderConfig,void * nativeConfig)136 void TngPrimaryPlane::setZOrderConfig(ZOrderConfig& zorderConfig,
137 void *nativeConfig)
138 {
139 if (!nativeConfig) {
140 ETRACE("Invalid parameter, no native config");
141 return;
142 }
143
144 mForceBottom = false;
145
146 int primaryIndex = -1;
147 int overlayIndex = -1;
148 // only consider force bottom when overlay is active
149 for (size_t i = 0; i < zorderConfig.size(); i++) {
150 DisplayPlane *plane = zorderConfig[i]->plane;
151 if (plane->getType() == DisplayPlane::PLANE_PRIMARY)
152 primaryIndex = i;
153 if (plane->getType() == DisplayPlane::PLANE_OVERLAY) {
154 overlayIndex = i;
155 }
156 }
157
158 // if has overlay plane which is below primary plane
159 if (overlayIndex > primaryIndex) {
160 mForceBottom = true;
161 }
162
163 struct intel_dc_plane_zorder *zorder =
164 (struct intel_dc_plane_zorder *)nativeConfig;
165 zorder->forceBottom[mIndex] = mForceBottom ? 1 : 0;
166 }
167
assignToDevice(int disp)168 bool TngPrimaryPlane::assignToDevice(int disp)
169 {
170 DisplayPlane::assignToDevice(disp);
171 return true;
172 }
173
174 } // namespace intel
175 } // namespace android
176