DisplayPlane.cpp revision ab302a7c5992e3668443dc9bdac481c108c20a34
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(0), 47 mPlaneAlpha(0), 48 mBlending(HWC_BLENDING_NONE), 49 mCurrentDataBuffer(0), 50 mUpdateMasks(0) 51{ 52 CTRACE(); 53 memset(&mPosition, 0, sizeof(mPosition)); 54 memset(&mSrcCrop, 0, sizeof(mSrcCrop)); 55} 56 57DisplayPlane::~DisplayPlane() 58{ 59 WARN_IF_NOT_DEINIT(); 60} 61 62bool DisplayPlane::initialize(uint32_t bufferCount) 63{ 64 CTRACE(); 65 66 if (bufferCount < MIN_DATA_BUFFER_COUNT) { 67 WTRACE("buffer count %d is too small", bufferCount); 68 bufferCount = MIN_DATA_BUFFER_COUNT; 69 } 70 71 // create buffer cache, adding few extra slots as buffer rendering is async 72 // buffer could still be queued in the display pipeline such that they 73 // can't be unmapped] 74 mCacheCapacity = bufferCount; 75 mDataBuffers.setCapacity(bufferCount); 76 mActiveBuffers.setCapacity(MIN_DATA_BUFFER_COUNT); 77 mInitialized = true; 78 return true; 79} 80 81void DisplayPlane::deinitialize() 82{ 83 // invalidate cached data buffers 84 if (mDataBuffers.size()) { 85 // invalidateBufferCache will assert if object is not initialized 86 // so invoking it only there is buffer to invalidate. 87 invalidateBufferCache(); 88 } 89 90 // invalidate active buffers 91 if (mActiveBuffers.size()) { 92 invalidateActiveBuffers(); 93 } 94 95 mCurrentDataBuffer = 0; 96 mInitialized = false; 97} 98 99void DisplayPlane::checkPosition(int& x, int& y, int& w, int& h) 100{ 101 drmModeModeInfoPtr mode = &mModeInfo; 102 103 if (mode->hdisplay == 0 || mode->vdisplay == 0) 104 return; 105 106 if (x < 0) 107 x = 0; 108 if (y < 0) 109 y = 0; 110 if ((x + w) > mode->hdisplay) 111 w = mode->hdisplay - x; 112 if ((y + h) > mode->vdisplay) 113 h = mode->vdisplay - y; 114} 115 116void DisplayPlane::setPosition(int x, int y, int w, int h) 117{ 118 ATRACE("Position = %d, %d - %dx%d", x, y, w, h); 119 120 if (mPosition.x != x || mPosition.y != y || 121 mPosition.w != w || mPosition.h != h) { 122 mUpdateMasks |= PLANE_POSITION_CHANGED; 123 mPosition.x = x; 124 mPosition.y = y; 125 mPosition.w = w; 126 mPosition.h = h; 127 } 128} 129 130void DisplayPlane::setSourceCrop(int x, int y, int w, int h) 131{ 132 ATRACE("Source crop = %d, %d - %dx%d", x, y, w, h); 133 134 if (mSrcCrop.x != x || mSrcCrop.y != y || 135 mSrcCrop.w != w || mSrcCrop.h != h) { 136 mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED; 137 mSrcCrop.x = x; 138 mSrcCrop.y = y; 139 mSrcCrop.w = w; 140 mSrcCrop.h = h; 141 } 142} 143 144void DisplayPlane::setTransform(int trans) 145{ 146 ATRACE("transform = %d", trans); 147 148 if (mTransform == trans) { 149 return; 150 } 151 152 mTransform = trans; 153 154 mUpdateMasks |= PLANE_TRANSFORM_CHANGED; 155} 156 157void DisplayPlane::setPlaneAlpha(uint8_t alpha, uint32_t blending) 158{ 159 ATRACE("plane alpha = 0x%x", alpha); 160 161 if (mPlaneAlpha != alpha) { 162 mPlaneAlpha = alpha; 163 mUpdateMasks |= PLANE_BUFFER_CHANGED; 164 } 165 166 if (mBlending != blending) { 167 mBlending = blending; 168 mUpdateMasks |= PLANE_BUFFER_CHANGED; 169 } 170} 171 172bool DisplayPlane::setDataBuffer(uint32_t handle) 173{ 174 DataBuffer *buffer; 175 BufferMapper *mapper; 176 ssize_t index; 177 bool ret; 178 bool isCompression; 179 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 180 181 RETURN_FALSE_IF_NOT_INIT(); 182 ATRACE("handle = %#x", handle); 183 184 if (!handle) { 185 WTRACE("invalid buffer handle"); 186 return false; 187 } 188 189 // do not need to update the buffer handle 190 if (mCurrentDataBuffer != handle) 191 mUpdateMasks |= PLANE_BUFFER_CHANGED; 192 193 // if no update then do Not need set data buffer 194 if (!mUpdateMasks) 195 return true; 196 197 buffer = bm->lockDataBuffer(handle); 198 if (!buffer) { 199 ETRACE("failed to get buffer"); 200 return false; 201 } 202 203 mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer); 204 isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer); 205 206 // map buffer if it's not in cache 207 index = mDataBuffers.indexOfKey(buffer->getKey()); 208 if (index < 0) { 209 VTRACE("unmapped buffer, mapping..."); 210 mapper = mapBuffer(buffer); 211 if (!mapper) { 212 ETRACE("failed to map buffer %#x", handle); 213 bm->unlockDataBuffer(buffer); 214 return false; 215 } 216 } else { 217 VTRACE("got mapper in saved data buffers and update source Crop"); 218 mapper = mDataBuffers.valueAt(index); 219 } 220 221 // always update source crop to mapper 222 mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h); 223 224 mapper->setIsCompression(isCompression); 225 226 // unlock buffer after getting mapper 227 bm->unlockDataBuffer(buffer); 228 buffer = NULL; 229 230 ret = setDataBuffer(*mapper); 231 if (ret) { 232 mCurrentDataBuffer = handle; 233 // update active buffers 234 updateActiveBuffers(mapper); 235 } 236 return ret; 237} 238 239BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer) 240{ 241 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 242 243 // invalidate buffer cache if cache is full 244 if ((int)mDataBuffers.size() >= mCacheCapacity) { 245 invalidateBufferCache(); 246 } 247 248 BufferMapper *mapper = bm->map(*buffer); 249 if (!mapper) { 250 ETRACE("failed to map buffer"); 251 return NULL; 252 } 253 254 // add it to data buffers 255 ssize_t index = mDataBuffers.add(buffer->getKey(), mapper); 256 if (index < 0) { 257 ETRACE("failed to add mapper"); 258 bm->unmap(mapper); 259 return NULL; 260 } 261 262 return mapper; 263} 264 265bool DisplayPlane::isActiveBuffer(BufferMapper *mapper) 266{ 267 for (size_t i = 0; i < mActiveBuffers.size(); i++) { 268 BufferMapper *activeMapper = mActiveBuffers.itemAt(i); 269 if (!activeMapper) 270 continue; 271 if (activeMapper->getKey() == mapper->getKey()) 272 return true; 273 } 274 275 return false; 276} 277 278void DisplayPlane::updateActiveBuffers(BufferMapper *mapper) 279{ 280 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 281 282 // unmap the first entry (oldest buffer) 283 if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) { 284 BufferMapper *oldest = mActiveBuffers.itemAt(0); 285 bm->unmap(oldest); 286 mActiveBuffers.removeAt(0); 287 } 288 289 // queue it to active buffers 290 if (!isActiveBuffer(mapper)) { 291 mapper->incRef(); 292 mActiveBuffers.push_back(mapper); 293 } 294} 295 296void DisplayPlane::invalidateActiveBuffers() 297{ 298 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 299 BufferMapper* mapper; 300 301 RETURN_VOID_IF_NOT_INIT(); 302 303 VTRACE("invalidating active buffers"); 304 305 for (size_t i = 0; i < mActiveBuffers.size(); i++) { 306 mapper = mActiveBuffers.itemAt(i); 307 // unmap it 308 bm->unmap(mapper); 309 } 310 311 // clear recorded data buffers 312 mActiveBuffers.clear(); 313} 314 315void DisplayPlane::invalidateBufferCache() 316{ 317 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 318 BufferMapper* mapper; 319 320 RETURN_VOID_IF_NOT_INIT(); 321 322 for (size_t i = 0; i < mDataBuffers.size(); i++) { 323 mapper = mDataBuffers.valueAt(i); 324 bm->unmap(mapper); 325 } 326 327 mDataBuffers.clear(); 328 // reset current buffer 329 mCurrentDataBuffer = 0; 330} 331 332bool DisplayPlane::assignToDevice(int disp) 333{ 334 RETURN_FALSE_IF_NOT_INIT(); 335 ATRACE("disp = %d", disp); 336 337 mDevice = disp; 338 339 Drm *drm = Hwcomposer::getInstance().getDrm(); 340 if (!drm->getModeInfo(mDevice, mModeInfo)) { 341 ETRACE("failed to get mode info"); 342 } 343 344 mPanelOrientation = drm->getPanelOrientation(mDevice); 345 346 return true; 347} 348 349bool DisplayPlane::flip(void *ctx) 350{ 351 RETURN_FALSE_IF_NOT_INIT(); 352 353 // always flip 354 return true; 355} 356 357void DisplayPlane::postFlip() 358{ 359 mUpdateMasks = 0; 360} 361 362bool DisplayPlane::reset() 363{ 364 // reclaim all allocated resources 365 if (mDataBuffers.size() > 0) { 366 invalidateBufferCache(); 367 } 368 369 if (mActiveBuffers.size() > 0) { 370 invalidateActiveBuffers(); 371 } 372 373 return true; 374} 375 376void DisplayPlane::setZOrder(int zorder) 377{ 378 mZOrder = zorder; 379} 380 381int DisplayPlane::getZOrder() const 382{ 383 return mZOrder; 384} 385 386} // namespace intel 387} // namespace android 388