void BufferManager::deinitialize() { mInitialized = false; if (mBufferPool) { // unmap & delete all cached buffer mappers for (size_t i = 0; i < mBufferPool->getCacheSize(); i++) { BufferMapper *mapper = mBufferPool->getMapper(i); mapper->unmap(); delete mapper; } delete mBufferPool; mBufferPool = NULL; } for (size_t j = 0; j < mFrameBuffers.size(); j++) { BufferMapper *mapper = mFrameBuffers.valueAt(j); mapper->unmap(); delete mapper; } mFrameBuffers.clear(); if (mGralloc) { gralloc_close_img(mGralloc); mGralloc = NULL; } if (mDataBuffer) { delete mDataBuffer; mDataBuffer = NULL; } }
bool DisplayPlane::isActiveBuffer(BufferMapper *mapper) { for (size_t i = 0; i < mActiveBuffers.size(); i++) { BufferMapper *activeMapper = mActiveBuffers.itemAt(i); if (!activeMapper) continue; if (activeMapper->getKey() == mapper->getKey()) return true; } return false; }
BufferMapper* BufferManager::map(DataBuffer& buffer) { bool ret; BufferMapper* mapper; CTRACE(); Mutex::Autolock _l(mLock); //try to get mapper from pool mapper = mBufferPool->getMapper(buffer.getKey()); if (mapper) { // increase mapper ref count mapper->incRef(); return mapper; } // create a new buffer mapper and add it to pool do { VLOGTRACE("new buffer, will add it"); mapper = createBufferMapper(buffer); if (!mapper) { ELOGTRACE("failed to allocate mapper"); break; } ret = mapper->map(); if (!ret) { ELOGTRACE("failed to map"); delete mapper; mapper = NULL; break; } ret = mBufferPool->addMapper(buffer.getKey(), mapper); if (!ret) { ELOGTRACE("failed to add mapper"); break; } // increase mapper ref count mapper->incRef(); return mapper; } while (0); // error handling if (mapper) { mapper->unmap(); delete mapper; } return NULL; }
void BufferManager::freeFrameBuffer(uint32_t fbHandle) { RETURN_VOID_IF_NOT_INIT(); if (!mGralloc) { WLOGTRACE("Alloc device is not available"); return; } ssize_t index = mFrameBuffers.indexOfKey(fbHandle); if (index < 0) { ELOGTRACE("invalid kernel handle"); return; } BufferMapper *mapper = mFrameBuffers.valueAt(index); uint32_t handle = mapper->getHandle(); mapper->putFbHandle(); delete mapper; mFrameBuffers.removeItem(fbHandle); gralloc_device_free_img(mGralloc, (buffer_handle_t)handle); }
void BufferManager::dump(Dump& d) { d.append("Buffer Manager status: pool size %d\n", mBufferPool->getCacheSize()); d.append("-------------------------------------------------------------\n"); for (size_t i = 0; i < mBufferPool->getCacheSize(); i++) { BufferMapper *mapper = mBufferPool->getMapper(i); d.append("Buffer %d: handle %#x, (%dx%d), format %d, refCount %d\n", i, mapper->getHandle(), mapper->getWidth(), mapper->getHeight(), mapper->getFormat(), mapper->getRef()); } return; }
bool TngSpritePlane::setDataBuffer(BufferMapper& mapper) { int bpp; int srcX, srcY; int dstX, dstY, dstW, dstH; uint32_t spriteFormat; uint32_t stride; uint32_t linoff; uint32_t planeAlpha; CTRACE(); // setup plane position dstX = mPosition.x; dstY = mPosition.y; dstW = mPosition.w; dstH = mPosition.h; checkPosition(dstX, dstY, dstW, dstH); // setup plane format if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) { ETRACE("unsupported format %#x", mapper.getFormat()); return false; } // setup stride and source buffer crop srcX = mapper.getCrop().x; srcY = mapper.getCrop().y; stride = mapper.getStride().rgb.stride; linoff = srcY * stride + srcX * bpp; // setup plane alpha if ((mBlending == HWC_BLENDING_PREMULT) && (mPlaneAlpha == 0)) { planeAlpha = mPlaneAlpha | 0x80000000; } else { // disable plane alpha to offload HW planeAlpha = 0; } // unlikely happen, but still we need make sure linoff is valid if (linoff > (stride * mapper.getHeight())) { ETRACE("invalid source crop"); return false; } // update context mContext.type = DC_SPRITE_PLANE; mContext.ctx.sp_ctx.index = mIndex; mContext.ctx.sp_ctx.pipe = mDevice; // none blending and BRGA format layer,set format to BGRX8888 if (mBlending == HWC_BLENDING_NONE && spriteFormat == PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888) mContext.ctx.sp_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRX8888 | 0x80000000; else mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000; mContext.ctx.sp_ctx.linoff = linoff; mContext.ctx.sp_ctx.stride = stride; mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12; mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); mContext.ctx.sp_ctx.size = ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff); mContext.ctx.sp_ctx.contalpa = planeAlpha; mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL; mContext.gtt_key = (uint64_t)mapper.getCpuAddress(0); VTRACE("cntr = %#x, linoff = %#x, stride = %#x," "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mContext.ctx.sp_ctx.cntr, mContext.ctx.sp_ctx.linoff, mContext.ctx.sp_ctx.stride, mContext.ctx.sp_ctx.surf, mContext.ctx.sp_ctx.pos, mContext.ctx.sp_ctx.size, mContext.ctx.sp_ctx.contalpa); return true; }
uint32_t BufferManager::allocFrameBuffer(int width, int height, int *stride) { RETURN_NULL_IF_NOT_INIT(); if (!mGralloc) { WLOGTRACE("Alloc device is not available"); return 0; } if (!width || !height || !stride) { ELOGTRACE("invalid input parameter"); return 0; } ILOGTRACE("size of frame buffer to create: %dx%d", width, height); uint32_t handle = 0; status_t err = gralloc_device_alloc_img( mGralloc, width, height, DrmConfig::getFrameBufferFormat(), 0, // GRALLOC_USAGE_HW_FB (buffer_handle_t *)&handle, stride); if (err != 0) { ELOGTRACE("failed to allocate frame buffer, error = %d", err); return 0; } DataBuffer *buffer = NULL; BufferMapper *mapper = NULL; do { buffer = lockDataBuffer(handle); if (!buffer) { ELOGTRACE("failed to get data buffer, handle = %#x", handle); break; } mapper = createBufferMapper(*buffer); if (!mapper) { ELOGTRACE("failed to create buffer mapper"); break; } uint32_t fbHandle; if (!(fbHandle = mapper->getFbHandle(0))) { ELOGTRACE("failed to get Fb handle"); break; } mFrameBuffers.add(fbHandle, mapper); unlockDataBuffer(buffer); return fbHandle; } while (0); // error handling, release all allocated resources if (buffer) { unlockDataBuffer(buffer); } if (mapper) { delete mapper; } gralloc_device_free_img(mGralloc, (buffer_handle_t)handle); return 0; }
bool DisplayPlane::setDataBuffer(uint32_t handle) { DataBuffer *buffer; BufferMapper *mapper; ssize_t index; bool ret; bool isCompression; BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); RETURN_FALSE_IF_NOT_INIT(); ALOGTRACE("handle = %#x", handle); if (!handle) { WLOGTRACE("invalid buffer handle"); return false; } // do not need to update the buffer handle if (mCurrentDataBuffer != handle) mUpdateMasks |= PLANE_BUFFER_CHANGED; // if no update then do Not need set data buffer if (!mUpdateMasks) return true; buffer = bm->lockDataBuffer(handle); if (!buffer) { ELOGTRACE("failed to get buffer"); return false; } mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer); isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer); // map buffer if it's not in cache index = mDataBuffers.indexOfKey(buffer->getKey()); if (index < 0) { VLOGTRACE("unmapped buffer, mapping..."); mapper = mapBuffer(buffer); if (!mapper) { ELOGTRACE("failed to map buffer %#x", handle); bm->unlockDataBuffer(buffer); return false; } } else { VLOGTRACE("got mapper in saved data buffers and update source Crop"); mapper = mDataBuffers.valueAt(index); } // always update source crop to mapper mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h); mapper->setIsCompression(isCompression); // unlock buffer after getting mapper bm->unlockDataBuffer(buffer); buffer = NULL; ret = setDataBuffer(*mapper); if (ret) { mCurrentDataBuffer = handle; // update active buffers updateActiveBuffers(mapper); } return ret; }