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