1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 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 27 namespace android { 28 namespace intel { 29 30 inline 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 38 inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y) 39 { 40 return !operator==(x, y); 41 } 42 43 inline 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 51 inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y) 52 { 53 return !operator==(x, y); 54 } 55 56 HwcLayer::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 96 HwcLayer::~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 110 bool 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 129 DisplayPlane* 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 140 void 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 171 uint32_t HwcLayer::getType() const 172 { 173 return mType; 174 } 175 176 void HwcLayer::setCompositionType(int32_t type) 177 { 178 mLayer->compositionType = type; 179 } 180 181 int32_t HwcLayer::getCompositionType() const 182 { 183 return mLayer->compositionType; 184 } 185 186 int HwcLayer::getIndex() const 187 { 188 return mIndex; 189 } 190 191 int HwcLayer::getZOrder() const 192 { 193 return mZOrder; 194 } 195 196 uint32_t HwcLayer::getFormat() const 197 { 198 return mFormat; 199 } 200 201 uint32_t HwcLayer::getBufferWidth() const 202 { 203 return mWidth; 204 } 205 206 uint32_t HwcLayer::getBufferHeight() const 207 { 208 return mHeight; 209 } 210 211 const stride_t& HwcLayer::getBufferStride() const 212 { 213 return mStride; 214 } 215 216 uint32_t HwcLayer::getUsage() const 217 { 218 return mUsage; 219 } 220 221 buffer_handle_t HwcLayer::getHandle() const 222 { 223 return mHandle; 224 } 225 226 uint32_t HwcLayer::getTransform() const 227 { 228 return mTransform; 229 } 230 231 bool HwcLayer::isProtected() const 232 { 233 return mIsProtected; 234 } 235 236 hwc_layer_1_t* HwcLayer::getLayer() const 237 { 238 return mLayer; 239 } 240 241 DisplayPlane* HwcLayer::getPlane() const 242 { 243 return mPlane; 244 } 245 246 void HwcLayer::setPriority(uint32_t priority) 247 { 248 mPriority = priority; 249 } 250 251 uint32_t HwcLayer::getPriority() const 252 { 253 return mPriority; 254 } 255 256 bool 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 317 bool HwcLayer::isUpdated() 318 { 319 return mUpdated; 320 } 321 322 uint32_t HwcLayer::getStaticCount() 323 { 324 return mStaticCount; 325 } 326 327 void 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 345 void 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