DisplayPlane.cpp revision 9f379685f09ddd7c4d98b23121487e8ac4b4dd40
1/* 2 * Copyright © 2012 Intel Corporation 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 * Authors: 25 * Jackie Li <yaodong.li@intel.com> 26 * 27 */ 28#include <HwcTrace.h> 29#include <Hwcomposer.h> 30#include <DisplayPlane.h> 31#include <GraphicBuffer.h> 32 33namespace android { 34namespace intel { 35 36DisplayPlane::DisplayPlane(int index, int type, int disp) 37 : mIndex(index), 38 mType(type), 39 mZOrder(-1), 40 mDevice(disp), 41 mInitialized(false), 42 mDataBuffers(), 43 mActiveBuffers(), 44 mCacheCapacity(0), 45 mIsProtectedBuffer(false), 46 mTransform(PLANE_TRANSFORM_0), 47 mPlaneAlpha(0), 48 mCurrentDataBuffer(0), 49 mUpdateMasks(0) 50{ 51 CTRACE(); 52 memset(&mPosition, 0, sizeof(mPosition)); 53 memset(&mSrcCrop, 0, sizeof(mSrcCrop)); 54} 55 56DisplayPlane::~DisplayPlane() 57{ 58 WARN_IF_NOT_DEINIT(); 59} 60 61bool DisplayPlane::initialize(uint32_t bufferCount) 62{ 63 CTRACE(); 64 65 if (bufferCount < MIN_DATA_BUFFER_COUNT) { 66 WTRACE("buffer count %d is too small", bufferCount); 67 bufferCount = MIN_DATA_BUFFER_COUNT; 68 } 69 70 // create buffer cache, adding few extra slots as buffer rendering is async 71 // buffer could still be queued in the display pipeline such that they 72 // can't be unmapped] 73 mCacheCapacity = bufferCount; 74 mDataBuffers.setCapacity(bufferCount); 75 mActiveBuffers.setCapacity(MIN_DATA_BUFFER_COUNT); 76 mInitialized = true; 77 return true; 78} 79 80void DisplayPlane::deinitialize() 81{ 82 // invalidate cached data buffers 83 if (mDataBuffers.size()) { 84 // invalidateBufferCache will assert if object is not initialized 85 // so invoking it only there is buffer to invalidate. 86 invalidateBufferCache(); 87 } 88 89 // invalidate active buffers 90 if (mActiveBuffers.size()) { 91 invalidateActiveBuffers(); 92 } 93 94 mCurrentDataBuffer = 0; 95 mInitialized = false; 96} 97 98void DisplayPlane::checkPosition(int& x, int& y, int& w, int& h) 99{ 100 Drm *drm = Hwcomposer::getInstance().getDrm(); 101 drmModeModeInfo modeInfo; 102 if (!drm->getModeInfo(mDevice, modeInfo)) { 103 ETRACE("failed to get mode info"); 104 return; 105 } 106 drmModeModeInfoPtr mode = &modeInfo; 107 108 if (x < 0) 109 x = 0; 110 if (y < 0) 111 y = 0; 112 if ((x + w) > mode->hdisplay) 113 w = mode->hdisplay - x; 114 if ((y + h) > mode->vdisplay) 115 h = mode->vdisplay - y; 116} 117 118void DisplayPlane::setPosition(int x, int y, int w, int h) 119{ 120 ATRACE("Position = %d, %d - %dx%d", x, y, w, h); 121 122 if (mPosition.x != x || mPosition.y != y || 123 mPosition.w != w || mPosition.h != h) { 124 mUpdateMasks |= PLANE_POSITION_CHANGED; 125 mPosition.x = x; 126 mPosition.y = y; 127 mPosition.w = w; 128 mPosition.h = h; 129 } 130} 131 132void DisplayPlane::setSourceCrop(int x, int y, int w, int h) 133{ 134 ATRACE("Source crop = %d, %d - %dx%d", x, y, w, h); 135 136 if (mSrcCrop.x != x || mSrcCrop.y != y || 137 mSrcCrop.w != w || mSrcCrop.h != h) { 138 mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED; 139 mSrcCrop.x = x; 140 mSrcCrop.y = y; 141 mSrcCrop.w = w; 142 mSrcCrop.h = h; 143 } 144} 145 146void DisplayPlane::setTransform(int trans) 147{ 148 ATRACE("transform = %d", trans); 149 150 if (mTransform == trans) { 151 return; 152 } 153 154 switch (trans) { 155 case PLANE_TRANSFORM_90: 156 case PLANE_TRANSFORM_180: 157 case PLANE_TRANSFORM_270: 158 mTransform = trans; 159 break; 160 default: 161 mTransform = PLANE_TRANSFORM_0; 162 break; 163 } 164 165 mUpdateMasks |= PLANE_TRANSFORM_CHANGED; 166} 167 168void DisplayPlane::setPlaneAlpha(uint8_t alpha) 169{ 170 ATRACE("plane alpha = 0x%x", alpha); 171 172 if (mPlaneAlpha != alpha) { 173 mPlaneAlpha = alpha; 174 } 175} 176 177bool DisplayPlane::setDataBuffer(uint32_t handle) 178{ 179 DataBuffer *buffer; 180 BufferMapper *mapper; 181 ssize_t index; 182 bool ret; 183 bool isCompression; 184 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 185 186 RETURN_FALSE_IF_NOT_INIT(); 187 ATRACE("handle = %#x", handle); 188 189 if (!handle) { 190 WTRACE("invalid buffer handle"); 191 return false; 192 } 193 194 // do not need to update the buffer handle 195 if (mCurrentDataBuffer != handle) 196 mUpdateMasks |= PLANE_BUFFER_CHANGED; 197 198 // if no update then do Not need set data buffer 199 if (!mUpdateMasks) 200 return true; 201 202 buffer = bm->lockDataBuffer(handle); 203 if (!buffer) { 204 ETRACE("failed to get buffer"); 205 return false; 206 } 207 208 mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer); 209 isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer); 210 211 // map buffer if it's not in cache 212 index = mDataBuffers.indexOfKey(buffer->getKey()); 213 if (index < 0) { 214 VTRACE("unmapped buffer, mapping..."); 215 mapper = mapBuffer(buffer); 216 if (!mapper) { 217 ETRACE("failed to map buffer %#x", handle); 218 bm->unlockDataBuffer(buffer); 219 return false; 220 } 221 } else { 222 VTRACE("got mapper in saved data buffers and update source Crop"); 223 mapper = mDataBuffers.valueAt(index); 224 } 225 226 // always update source crop to mapper 227 mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h); 228 229 mapper->setIsCompression(isCompression); 230 231 // unlock buffer after getting mapper 232 bm->unlockDataBuffer(buffer); 233 buffer = NULL; 234 235 ret = setDataBuffer(*mapper); 236 if (ret) { 237 mCurrentDataBuffer = handle; 238 // update active buffers 239 updateActiveBuffers(mapper); 240 } 241 return ret; 242} 243 244BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer) 245{ 246 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 247 248 // invalidate buffer cache if cache is full 249 if ((int)mDataBuffers.size() >= mCacheCapacity) { 250 invalidateBufferCache(); 251 } 252 253 BufferMapper *mapper = bm->map(*buffer); 254 if (!mapper) { 255 ETRACE("failed to map buffer"); 256 return NULL; 257 } 258 259 // add it to data buffers 260 ssize_t index = mDataBuffers.add(buffer->getKey(), mapper); 261 if (index < 0) { 262 ETRACE("failed to add mapper"); 263 bm->unmap(mapper); 264 return NULL; 265 } 266 267 return mapper; 268} 269 270bool DisplayPlane::isActiveBuffer(BufferMapper *mapper) 271{ 272 for (size_t i = 0; i < mActiveBuffers.size(); i++) { 273 BufferMapper *activeMapper = mActiveBuffers.itemAt(i); 274 if (!activeMapper) 275 continue; 276 if (activeMapper->getKey() == mapper->getKey()) 277 return true; 278 } 279 280 return false; 281} 282 283void DisplayPlane::updateActiveBuffers(BufferMapper *mapper) 284{ 285 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 286 287 // unmap the first entry (oldest buffer) 288 if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) { 289 BufferMapper *oldest = mActiveBuffers.itemAt(0); 290 bm->unmap(oldest); 291 mActiveBuffers.removeAt(0); 292 } 293 294 // queue it to active buffers 295 if (!isActiveBuffer(mapper)) { 296 mapper->incRef(); 297 mActiveBuffers.push_back(mapper); 298 } 299} 300 301void DisplayPlane::invalidateActiveBuffers() 302{ 303 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 304 BufferMapper* mapper; 305 306 RETURN_VOID_IF_NOT_INIT(); 307 308 VTRACE("invalidating active buffers"); 309 310 for (size_t i = 0; i < mActiveBuffers.size(); i++) { 311 mapper = mActiveBuffers.itemAt(i); 312 // unmap it 313 bm->unmap(mapper); 314 } 315 316 // clear recorded data buffers 317 mActiveBuffers.clear(); 318} 319 320void DisplayPlane::invalidateBufferCache() 321{ 322 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 323 BufferMapper* mapper; 324 325 RETURN_VOID_IF_NOT_INIT(); 326 327 for (size_t i = 0; i < mDataBuffers.size(); i++) { 328 mapper = mDataBuffers.valueAt(i); 329 bm->unmap(mapper); 330 } 331 332 mDataBuffers.clear(); 333 // reset current buffer 334 mCurrentDataBuffer = 0; 335} 336 337bool DisplayPlane::assignToDevice(int disp) 338{ 339 RETURN_FALSE_IF_NOT_INIT(); 340 ATRACE("disp = %d", disp); 341 342 mDevice = disp; 343 return true; 344} 345 346bool DisplayPlane::flip(void *ctx) 347{ 348 RETURN_FALSE_IF_NOT_INIT(); 349 350 // always flip 351 return true; 352} 353 354void DisplayPlane::postFlip() 355{ 356 mUpdateMasks = 0; 357} 358 359bool DisplayPlane::reset() 360{ 361 // reclaim all allocated resources 362 if (mDataBuffers.size() > 0) { 363 invalidateBufferCache(); 364 } 365 366 if (mActiveBuffers.size() > 0) { 367 invalidateActiveBuffers(); 368 } 369 370 return true; 371} 372 373void DisplayPlane::setZOrder(int zorder) 374{ 375 mZOrder = zorder; 376} 377 378int DisplayPlane::getZOrder() const 379{ 380 return mZOrder; 381} 382 383} // namespace intel 384} // namespace android 385