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 <HwcLayer.h> 19#include <Hwcomposer.h> 20#include <GraphicBuffer.h> 21#include <IDisplayDevice.h> 22#include <DisplayQuery.h> 23#include <PlaneCapabilities.h> 24#include <cutils/properties.h> 25 26 27namespace android { 28namespace intel { 29 30inline bool operator==(const hwc_rect_t& x, const hwc_rect_t& y) 31{ 32 return (x.top == y.top && 33 x.bottom == y.bottom && 34 x.left == y.left && 35 x.right == y.right); 36} 37 38inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y) 39{ 40 return !operator==(x, y); 41} 42 43inline bool operator ==(const hwc_frect_t& x, const hwc_frect_t& y) 44{ 45 return (x.top == y.top && 46 x.bottom == y.bottom && 47 x.left == y.left && 48 x.right == y.right); 49} 50 51inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y) 52{ 53 return !operator==(x, y); 54} 55 56HwcLayer::HwcLayer(int index, hwc_layer_1_t *layer) 57 : mIndex(index), 58 mZOrder(index + 1), // 0 is reserved for frame buffer target 59 mDevice(0), 60 mLayer(layer), 61 mPlane(0), 62 mFormat(DataBuffer::FORMAT_INVALID), 63 mWidth(0), 64 mHeight(0), 65 mUsage(0), 66 mHandle(0), 67 mIsProtected(false), 68 mType(LAYER_FB), 69 mPriority(0), 70 mTransform(0), 71 mStaticCount(0), 72 mUpdated(false) 73{ 74 memset(&mSourceCropf, 0, sizeof(mSourceCropf)); 75 memset(&mDisplayFrame, 0, sizeof(mDisplayFrame)); 76 memset(&mStride, 0, sizeof(mStride)); 77 78 mPlaneCandidate = false; 79 setupAttributes(); 80 81#ifdef HWC_TRACE_FPS 82 mTraceFps = false; 83 char prop[PROPERTY_VALUE_MAX]; 84 if (property_get("debug.hwc.fps_trace.enable", prop, "0") > 0) { 85 mTraceFps = atoi(prop); 86 } 87 mLastHandle = NULL; 88 89 if (mTraceFps) { 90 // holding up to 6 seconds of samples at 60Hz 91 mFrames.setCapacity(6 * 60); 92 } 93#endif 94} 95 96HwcLayer::~HwcLayer() 97{ 98 if (mPlane) { 99 WTRACE("HwcLayer is not cleaned up"); 100 } 101 102 mLayer = NULL; 103 mPlane = NULL; 104 105#ifdef HWC_TRACE_FPS 106 mFrames.clear(); 107#endif 108} 109 110bool HwcLayer::attachPlane(DisplayPlane* plane, int device) 111{ 112 if (mPlane) { 113 ETRACE("failed to attach plane, plane exists"); 114 return false; 115 } 116 117 if (!plane) { 118 ETRACE("Invalid plane"); 119 return false; 120 } 121 122 mDevice = device; 123 //plane->setZOrder(mIndex); 124 plane->assignToDevice(device); 125 mPlane = plane; 126 return true; 127} 128 129DisplayPlane* HwcLayer::detachPlane() 130{ 131 // reset plane's z order 132 if (mPlane) 133 mPlane->setZOrder(-1); 134 DisplayPlane *plane = mPlane; 135 mPlane = 0; 136 mDevice = 0; 137 return plane; 138} 139 140void HwcLayer::setType(uint32_t type) 141{ 142 if (!mLayer) 143 return; 144 145 switch (type) { 146 case LAYER_OVERLAY: 147 case LAYER_SKIPPED: 148 mLayer->compositionType = HWC_OVERLAY; 149 mLayer->hints |= HWC_HINT_CLEAR_FB; 150 break; 151 // NOTE: set compositionType to HWC_FRAMEBUFFER here so that we have 152 // a chance to submit the primary changes to HW. 153 // Upper layer HWComposer will reset the compositionType automatically. 154 case LAYER_FB: 155 case LAYER_FORCE_FB: 156 mLayer->compositionType = HWC_FRAMEBUFFER; 157 break; 158 case LAYER_SIDEBAND: 159 mLayer->compositionType = HWC_SIDEBAND; 160 break; 161 case LAYER_CURSOR_OVERLAY: 162 mLayer->compositionType = HWC_CURSOR_OVERLAY; 163 break; 164 default: 165 break; 166 } 167 168 mType = type; 169} 170 171uint32_t HwcLayer::getType() const 172{ 173 return mType; 174} 175 176void HwcLayer::setCompositionType(int32_t type) 177{ 178 mLayer->compositionType = type; 179} 180 181int32_t HwcLayer::getCompositionType() const 182{ 183 return mLayer->compositionType; 184} 185 186int HwcLayer::getIndex() const 187{ 188 return mIndex; 189} 190 191int HwcLayer::getZOrder() const 192{ 193 return mZOrder; 194} 195 196uint32_t HwcLayer::getFormat() const 197{ 198 return mFormat; 199} 200 201uint32_t HwcLayer::getBufferWidth() const 202{ 203 return mWidth; 204} 205 206uint32_t HwcLayer::getBufferHeight() const 207{ 208 return mHeight; 209} 210 211const stride_t& HwcLayer::getBufferStride() const 212{ 213 return mStride; 214} 215 216uint32_t HwcLayer::getUsage() const 217{ 218 return mUsage; 219} 220 221buffer_handle_t HwcLayer::getHandle() const 222{ 223 return mHandle; 224} 225 226uint32_t HwcLayer::getTransform() const 227{ 228 return mTransform; 229} 230 231bool HwcLayer::isProtected() const 232{ 233 return mIsProtected; 234} 235 236hwc_layer_1_t* HwcLayer::getLayer() const 237{ 238 return mLayer; 239} 240 241DisplayPlane* HwcLayer::getPlane() const 242{ 243 return mPlane; 244} 245 246void HwcLayer::setPriority(uint32_t priority) 247{ 248 mPriority = priority; 249} 250 251uint32_t HwcLayer::getPriority() const 252{ 253 return mPriority; 254} 255 256bool HwcLayer::update(hwc_layer_1_t *layer) 257{ 258 // update layer 259 mLayer = layer; 260 setupAttributes(); 261 262#ifdef HWC_TRACE_FPS 263 if (mTraceFps && mLayer && mLayer->compositionType != HWC_FRAMEBUFFER_TARGET ) { 264 // 1 second = 1000000000 nano seconds 265 uint64_t now = systemTime(CLOCK_MONOTONIC); 266 if (mLastHandle != mHandle) { 267 mLastHandle = mHandle; 268 mFrames.push(now); 269 } 270 // calculate fps in 5-second time window 271 int frames = mFrames.size(); 272 while (frames && now - mFrames[0] > 5000000000LL) { 273 mFrames.removeItemsAt(0); 274 frames--; 275 } 276 double fps = 0; 277 if (frames > 1) { 278 fps = frames * 1000000000.0/ (now - mFrames[0]); 279 } 280 ITRACE("fps of layer %d is %.1f", mIndex, fps); 281 } 282#endif 283 284 // if not a FB layer & a plane was attached update plane's data buffer 285 if (mPlane) { 286 mPlane->setPosition(layer->displayFrame.left, 287 layer->displayFrame.top, 288 layer->displayFrame.right - layer->displayFrame.left, 289 layer->displayFrame.bottom - layer->displayFrame.top); 290 mPlane->setSourceCrop(layer->sourceCropf.left, 291 layer->sourceCropf.top, 292 layer->sourceCropf.right - layer->sourceCropf.left, 293 layer->sourceCropf.bottom - layer->sourceCropf.top); 294 mPlane->setTransform(layer->transform); 295 mPlane->setPlaneAlpha(layer->planeAlpha, layer->blending); 296 bool ret = mPlane->setDataBuffer(layer->handle); 297 if (ret == true) { 298 return true; 299 } 300 DTRACE("failed to set data buffer, reset handle to 0!!"); 301 mHandle = 0; 302 if (!mIsProtected) { 303 // typical case: rotated buffer is not ready or handle is null 304 return false; 305 } else { 306 // protected video has to be rendered using overlay. 307 // if buffer is not ready overlay will still be attached to this layer 308 // but rendering needs to be skipped. 309 WTRACE("ignoring result of data buffer setting for protected video"); 310 return true; 311 } 312 } 313 314 return true; 315} 316 317bool HwcLayer::isUpdated() 318{ 319 return mUpdated; 320} 321 322uint32_t HwcLayer::getStaticCount() 323{ 324 return mStaticCount; 325} 326 327void HwcLayer::postFlip() 328{ 329 mUpdated = false; 330 if (mPlane) { 331 mPlane->postFlip(); 332 333 // flip frame buffer target once in video extended mode to refresh screen, 334 // then mark type as LAYER_SKIPPED so it will not be flipped again. 335 // by doing this pipe for primary device can enter idle state 336 if (mDevice == IDisplayDevice::DEVICE_PRIMARY && 337 mType == LAYER_FRAMEBUFFER_TARGET && 338 Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) { 339 DTRACE("Skipping frame buffer target..."); 340 mType = LAYER_SKIPPED; 341 } 342 } 343} 344 345void HwcLayer::setupAttributes() 346{ 347 if ((mLayer->flags & HWC_SKIP_LAYER) || 348 mTransform != mLayer->transform || 349 mSourceCropf != mLayer->sourceCropf || 350 mDisplayFrame != mLayer->displayFrame || 351 mHandle != mLayer->handle || 352 DisplayQuery::isVideoFormat(mFormat)) { 353 // TODO: same handle does not mean there is always no update 354 mUpdated = true; 355 mStaticCount = 0; 356 } else { 357 // protect it from exceeding its max 358 if (++mStaticCount > 1000) 359 mStaticCount = LAYER_STATIC_THRESHOLD + 1; 360 } 361 362 // update handle always as it can become "NULL" 363 // if the given layer is not ready 364 mTransform = mLayer->transform; 365 mSourceCropf = mLayer->sourceCropf; 366 mDisplayFrame = mLayer->displayFrame; 367 mHandle = mLayer->handle; 368 369 if (mFormat != DataBuffer::FORMAT_INVALID) { 370 // other attributes have been set. 371 return; 372 } 373 374 if (mLayer->handle == NULL) { 375 VTRACE("invalid handle"); 376 return; 377 } 378 379 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 380 if (bm == NULL) { 381 // TODO: this check is redundant 382 return; 383 } 384 385 DataBuffer *buffer = bm->lockDataBuffer(mLayer->handle); 386 if (!buffer) { 387 ETRACE("failed to get buffer"); 388 } else { 389 mFormat = buffer->getFormat(); 390 mWidth = buffer->getWidth(); 391 mHeight = buffer->getHeight(); 392 mStride = buffer->getStride(); 393 mPriority = (mSourceCropf.right - mSourceCropf.left) * (mSourceCropf.bottom - mSourceCropf.top); 394 mPriority <<= LAYER_PRIORITY_SIZE_OFFSET; 395 mPriority |= mIndex; 396 GraphicBuffer *gBuffer = (GraphicBuffer*)buffer; 397 mUsage = gBuffer->getUsage(); 398 mIsProtected = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer); 399 if (mIsProtected) { 400 mPriority |= LAYER_PRIORITY_PROTECTED; 401 } else if (PlaneCapabilities::isFormatSupported(DisplayPlane::PLANE_OVERLAY, this)) { 402 mPriority |= LAYER_PRIORITY_OVERLAY; 403 } 404 bm->unlockDataBuffer(buffer); 405 } 406} 407 408} // namespace intel 409} // namespace android 410