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 <common/utils/HwcTrace.h> 17#include <common/base/Drm.h> 18#include <common/base/HwcLayer.h> 19#include <Hwcomposer.h> 20#include <GraphicBuffer.h> 21#include <IDisplayDevice.h> 22#include <DisplayQuery.h> 23#include <PlaneCapabilities.h> 24 25 26namespace android { 27namespace intel { 28 29inline bool operator==(const hwc_rect_t& x, const hwc_rect_t& y) 30{ 31 return (x.top == y.top && 32 x.bottom == y.bottom && 33 x.left == y.left && 34 x.right == y.right); 35} 36 37inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y) 38{ 39 return !operator==(x, y); 40} 41 42inline bool operator ==(const hwc_frect_t& x, const hwc_frect_t& y) 43{ 44 return (x.top == y.top && 45 x.bottom == y.bottom && 46 x.left == y.left && 47 x.right == y.right); 48} 49 50inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y) 51{ 52 return !operator==(x, y); 53} 54 55HwcLayer::HwcLayer(int index, hwc_layer_1_t *layer) 56 : mIndex(index), 57 mZOrder(index + 1), // 0 is reserved for frame buffer target 58 mDevice(0), 59 mLayer(layer), 60 mPlane(0), 61 mFormat(DataBuffer::FORMAT_INVALID), 62 mWidth(0), 63 mHeight(0), 64 mUsage(0), 65 mHandle(0), 66 mIsProtected(false), 67 mType(LAYER_FB), 68 mPriority(0), 69 mTransform(0), 70 mUpdated(false) 71{ 72 memset(&mSourceCropf, 0, sizeof(mSourceCropf)); 73 memset(&mDisplayFrame, 0, sizeof(mDisplayFrame)); 74 memset(&mStride, 0, sizeof(mStride)); 75 76 mPlaneCandidate = false; 77 setupAttributes(); 78} 79 80HwcLayer::~HwcLayer() 81{ 82 if (mPlane) { 83 WLOGTRACE("HwcLayer is not cleaned up"); 84 } 85 86 mLayer = NULL; 87 mPlane = NULL; 88} 89 90bool HwcLayer::attachPlane(DisplayPlane* plane, int device) 91{ 92 if (mPlane) { 93 ELOGTRACE("failed to attach plane, plane exists"); 94 return false; 95 } 96 97 if (!plane) { 98 ELOGTRACE("Invalid plane"); 99 return false; 100 } 101 102 mDevice = device; 103 //plane->setZOrder(mIndex); 104 plane->assignToDevice(device); 105 mPlane = plane; 106 return true; 107} 108 109DisplayPlane* HwcLayer::detachPlane() 110{ 111 // reset plane's z order 112 if (mPlane) 113 mPlane->setZOrder(-1); 114 DisplayPlane *plane = mPlane; 115 mPlane = 0; 116 mDevice = 0; 117 return plane; 118} 119 120void HwcLayer::setType(uint32_t type) 121{ 122 if (!mLayer) 123 return; 124 125 switch (type) { 126 case LAYER_OVERLAY: 127 case LAYER_SKIPPED: 128 mLayer->compositionType = HWC_OVERLAY; 129 mLayer->hints |= HWC_HINT_CLEAR_FB; 130 break; 131 // NOTE: set compositionType to HWC_FRAMEBUFFER here so that we have 132 // a chance to submit the primary changes to HW. 133 // Upper layer HWComposer will reset the compositionType automatically. 134 case LAYER_FB: 135 case LAYER_FORCE_FB: 136 mLayer->compositionType = HWC_FRAMEBUFFER; 137 break; 138 case LAYER_SIDEBAND: 139 mLayer->compositionType = HWC_SIDEBAND; 140 break; 141 case LAYER_CURSOR_OVERLAY: 142 mLayer->compositionType = HWC_CURSOR_OVERLAY; 143 break; 144 default: 145 break; 146 } 147 148 mType = type; 149} 150 151uint32_t HwcLayer::getType() const 152{ 153 return mType; 154} 155 156void HwcLayer::setCompositionType(int32_t type) 157{ 158 mLayer->compositionType = type; 159} 160 161int32_t HwcLayer::getCompositionType() const 162{ 163 return mLayer->compositionType; 164} 165 166int HwcLayer::getIndex() const 167{ 168 return mIndex; 169} 170 171int HwcLayer::getZOrder() const 172{ 173 return mZOrder; 174} 175 176uint32_t HwcLayer::getFormat() const 177{ 178 return mFormat; 179} 180 181uint32_t HwcLayer::getBufferWidth() const 182{ 183 return mWidth; 184} 185 186uint32_t HwcLayer::getBufferHeight() const 187{ 188 return mHeight; 189} 190 191const stride_t& HwcLayer::getBufferStride() const 192{ 193 return mStride; 194} 195 196uint32_t HwcLayer::getUsage() const 197{ 198 return mUsage; 199} 200 201uint32_t HwcLayer::getHandle() const 202{ 203 return mHandle; 204} 205 206uint32_t HwcLayer::getTransform() const 207{ 208 return mTransform; 209} 210 211bool HwcLayer::isProtected() const 212{ 213 return mIsProtected; 214} 215 216hwc_layer_1_t* HwcLayer::getLayer() const 217{ 218 return mLayer; 219} 220 221DisplayPlane* HwcLayer::getPlane() const 222{ 223 return mPlane; 224} 225 226void HwcLayer::setPriority(uint32_t priority) 227{ 228 mPriority = priority; 229} 230 231uint32_t HwcLayer::getPriority() const 232{ 233 return mPriority; 234} 235 236bool HwcLayer::update(hwc_layer_1_t *layer) 237{ 238 // update layer 239 mLayer = layer; 240 setupAttributes(); 241 242 // if not a FB layer & a plane was attached update plane's data buffer 243 if (mPlane) { 244 mPlane->setPosition(layer->displayFrame.left, 245 layer->displayFrame.top, 246 layer->displayFrame.right - layer->displayFrame.left, 247 layer->displayFrame.bottom - layer->displayFrame.top); 248 mPlane->setSourceCrop(layer->sourceCropf.left, 249 layer->sourceCropf.top, 250 layer->sourceCropf.right - layer->sourceCropf.left, 251 layer->sourceCropf.bottom - layer->sourceCropf.top); 252 mPlane->setTransform(layer->transform); 253 mPlane->setPlaneAlpha(layer->planeAlpha, layer->blending); 254 bool ret = mPlane->setDataBuffer((uint32_t)layer->handle); 255 if (ret == true) { 256 return true; 257 } 258 DLOGTRACE("failed to set data buffer, reset handle to 0!!"); 259 mHandle = 0; 260 if (!mIsProtected) { 261 // typical case: rotated buffer is not ready or handle is null 262 return false; 263 } else { 264 // protected video has to be rendered using overlay. 265 // if buffer is not ready overlay will still be attached to this layer 266 // but rendering needs to be skipped. 267 WLOGTRACE("ignoring result of data buffer setting for protected video"); 268 return true; 269 } 270 } 271 272 return true; 273} 274 275bool HwcLayer::isUpdated() 276{ 277 return mUpdated; 278} 279 280void HwcLayer::postFlip() 281{ 282 mUpdated = false; 283 if (mPlane) { 284 mPlane->postFlip(); 285 } 286} 287 288void HwcLayer::setupAttributes() 289{ 290 if ((mLayer->flags & HWC_SKIP_LAYER) || 291 mTransform != mLayer->transform || 292 mSourceCropf != mLayer->sourceCropf || 293 mDisplayFrame != mLayer->displayFrame || 294 mHandle != (uint32_t)mLayer->handle || 295 DisplayQuery::isVideoFormat(mFormat)) { 296 // TODO: same handle does not mean there is always no update 297 mUpdated = true; 298 } 299 300 // update handle always as it can become "NULL" 301 // if the given layer is not ready 302 mTransform = mLayer->transform; 303 mSourceCropf = mLayer->sourceCropf; 304 mDisplayFrame = mLayer->displayFrame; 305 mHandle = (uint32_t)mLayer->handle; 306 307 if (mFormat != DataBuffer::FORMAT_INVALID) { 308 // other attributes have been set. 309 return; 310 } 311 312 if (mLayer->handle == NULL) { 313 VLOGTRACE("invalid handle"); 314 return; 315 } 316 317 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 318 if (bm == NULL) { 319 // TODO: this check is redundant 320 return; 321 } 322 323 DataBuffer *buffer = bm->lockDataBuffer((uint32_t)mLayer->handle); 324 if (!buffer) { 325 ELOGTRACE("failed to get buffer"); 326 } else { 327 mFormat = buffer->getFormat(); 328 mWidth = buffer->getWidth(); 329 mHeight = buffer->getHeight(); 330 mStride = buffer->getStride(); 331 mPriority = (mSourceCropf.right - mSourceCropf.left) * (mSourceCropf.bottom - mSourceCropf.top); 332 mPriority <<= LAYER_PRIORITY_SIZE_OFFSET; 333 mPriority |= mIndex; 334 GraphicBuffer *gBuffer = (GraphicBuffer*)buffer; 335 mUsage = gBuffer->getUsage(); 336 mIsProtected = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer); 337 if (mIsProtected) { 338 mPriority |= LAYER_PRIORITY_PROTECTED; 339 } else if (PlaneCapabilities::isFormatSupported(DisplayPlane::PLANE_OVERLAY, this)) { 340 mPriority |= LAYER_PRIORITY_OVERLAY; 341 } 342 bm->unlockDataBuffer(buffer); 343 } 344} 345 346} // namespace intel 347} // namespace android 348