int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage, buffer_handle_t* pHandle) { private_module_t* m = reinterpret_cast<private_module_t*>(common.module); // we don't support allocations with both the FB and PMEM_ADSP flags if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) { return -EINVAL; } // allocate the framebuffer if (m->framebuffer == NULL) { // initialize the framebuffer, the framebuffer is mapped once // and forever. int err = deps.mapFrameBufferLocked(m); if (err < 0) { return err; } } const uint32_t bufferMask = m->bufferMask; const uint32_t numBuffers = m->numBuffers; const size_t bufferSize = m->finfo.line_length * m->info.yres; if (numBuffers == 1) { // If we have only one buffer, we never use page-flipping. Instead, // we return a regular buffer which will be memcpy'ed to the main // screen when post is called. int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI, m->fbFormat, m->info.xres, m->info.yres); } if (bufferMask >= ((1LU<<numBuffers)-1)) { // We ran out of buffers. return -ENOMEM; } // create a "fake" handles for it intptr_t vaddr = intptr_t(m->framebuffer->base); private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), bufferSize, private_handle_t::PRIV_FLAGS_USES_PMEM | private_handle_t::PRIV_FLAGS_FRAMEBUFFER, BUFFER_TYPE_UI, m->fbFormat, m->info.xres, m->info.yres); // find a free slot for (uint32_t i=0 ; i<numBuffers ; i++) { if ((bufferMask & (1LU<<i)) == 0) { m->bufferMask |= (1LU<<i); break; } vaddr += bufferSize; } hnd->base = vaddr; hnd->offset = vaddr - intptr_t(m->framebuffer->base); *pHandle = hnd; return 0; }
static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev, size_t size, int usage, buffer_handle_t* pHandle) { private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module); // allocate the framebuffer if (m->framebuffer == NULL) { // initialize the framebuffer, the framebuffer is mapped once and forever. int err = init_frame_buffer_locked(m); if (err < 0) { return err; } } const uint32_t bufferMask = m->bufferMask; const uint32_t numBuffers = m->numBuffers; const size_t bufferSize = m->finfo.line_length * m->info.yres; if (numBuffers == 1) { // If we have only one buffer, we never use page-flipping. Instead, // we return a regular buffer which will be memcpy'ed to the main // screen when post is called. int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; LOGE("fallback to single buffering"); return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle); } if (bufferMask >= ((1LU<<numBuffers)-1)) { // We ran out of buffers. return -ENOMEM; } int vaddr = m->framebuffer->base; // find a free slot for (uint32_t i=0 ; i<numBuffers ; i++) { if ((bufferMask & (1LU<<i)) == 0) { m->bufferMask |= (1LU<<i); break; } vaddr += bufferSize; } // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory private_handle_t* hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, size, vaddr, 0, dup(m->framebuffer->fd), vaddr - m->framebuffer->base); *pHandle = hnd; return 0; }
int gpu_context_t::alloc_impl(int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride) { if (!pHandle || !pStride) return -EINVAL; size_t size, alignedw, alignedh; alignedw = ALIGN(w, 32); alignedh = ALIGN(h, 32); switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: size = alignedw * alignedh * 4; break; case HAL_PIXEL_FORMAT_RGB_888: size = alignedw * alignedh * 3; break; case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_RGBA_5551: case HAL_PIXEL_FORMAT_RGBA_4444: size = alignedw * alignedh * 2; break; // adreno formats case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 size = ALIGN(alignedw*alignedh, 4096); size += ALIGN(2 * ALIGN(w/2, 32) * ALIGN(h/2, 32), 4096); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12 // The chroma plane is subsampled, // but the pitch in bytes is unchanged // The GPU needs 4K alignment, but the video decoder needs 8K alignedw = ALIGN(w, 128); size = ALIGN( alignedw * alignedh, 8192); size += ALIGN( alignedw * ALIGN(h/2, 32), 4096); break; case HAL_PIXEL_FORMAT_YV12: if ((w&1) || (h&1)) { LOGE("w or h is odd for HAL_PIXEL_FORMAT_YV12"); return -EINVAL; } alignedw = ALIGN(w, 16); alignedh = h; size = alignedw*alignedh + (ALIGN(alignedw/2, 16) * (alignedh/2))*2; break; default: LOGE("unrecognized pixel format: %d", format); return -EINVAL; } if ((ssize_t)size <= 0) return -EINVAL; int err; if (usage & GRALLOC_USAGE_HW_FB) { err = gralloc_alloc_framebuffer(size, usage, pHandle); } else { err = gralloc_alloc_buffer(size, usage, pHandle); } if (err < 0) { return err; } *pStride = alignedw; return 0; }
static int alloc_device_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride) { if (!pHandle || !pStride) { return -EINVAL; } size_t size; size_t stride; if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCbCr_422_SP || format == HAL_PIXEL_FORMAT_YV12 ) { int vstride; switch (format) { case HAL_PIXEL_FORMAT_YCbCr_420_SP: stride = (w + 1) & ~1; size = stride * h * 2; break; case HAL_PIXEL_FORMAT_YCbCr_422_SP: stride = (w + 1) & ~1; vstride = (h+1) & ~1; size = (stride * vstride) + (w/2 * h/2) * 2; break; case HAL_PIXEL_FORMAT_YV12: stride = (w + 15) & ~15; size = h * (stride + stride/2); break; default: return -EINVAL; } } else { int align = 8; int bpp = 0; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: bpp = 4; break; case HAL_PIXEL_FORMAT_RGB_888: bpp = 3; break; case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_RGBA_5551: case HAL_PIXEL_FORMAT_RGBA_4444: bpp = 2; break; default: return -EINVAL; } size_t bpr = (w*bpp + (align-1)) & ~(align-1); size = bpr * h; stride = bpr / bpp; } int err; if (usage & GRALLOC_USAGE_HW_FB) { err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); } else { err = gralloc_alloc_buffer(dev, size, usage, pHandle); } if (err < 0) { return err; } *pStride = stride; return 0; }
static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle, int *pStride) { if (!pHandle || !pStride) { return -EINVAL; } size_t size; size_t stride; if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12) { switch (format) { case HAL_PIXEL_FORMAT_YCrCb_420_SP: stride = GRALLOC_ALIGN(w, 16); if (usage & GRALLOC_USAGE_PRIVATE_1){ /************************************************************ * * height is 16bytes aligned for encode canvas read * * with 16bytes align. width is 32bytes aligned for * * ge2d working with 256bit once that is 32bytes * ************************************************************/ size = GRALLOC_ALIGN(h, 16) * (GRALLOC_ALIGN(w, 32) + GRALLOC_ALIGN(stride/2,16)); }else { size = h * (stride + GRALLOC_ALIGN(stride/2,16)); } break; case HAL_PIXEL_FORMAT_YV12: stride = GRALLOC_ALIGN(w, 16); if (usage & GRALLOC_USAGE_PRIVATE_1){ /************************************************************ * * height is 16bytes aligned for encode canvas read * * with 16bytes align. width is 32bytes aligned for * * ge2d working with 256bit once that is 32bytes * ************************************************************/ size = GRALLOC_ALIGN(h, 16) * (GRALLOC_ALIGN(w, 64) + GRALLOC_ALIGN(stride/2,32)); }else { size = h * (stride + GRALLOC_ALIGN(stride/2,16)); } break; default: return -EINVAL; } } else { int bpp = 0; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: bpp = 4; break; case HAL_PIXEL_FORMAT_RGB_888: bpp = 3; break; case HAL_PIXEL_FORMAT_RGB_565: bpp = 2; break; default: return -EINVAL; } size_t bpr = GRALLOC_ALIGN(w * bpp, 64); size = bpr * h; stride = bpr / bpp; } int err; #ifndef MALI_600 if (usage & GRALLOC_USAGE_HW_FB) { err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); } else #endif { err = gralloc_alloc_buffer(dev, size, usage, pHandle); if (err < 0) { return err; } private_handle_t* hnd = (private_handle_t*)(*pHandle); hnd->format = format; } *pStride = stride; return 0; }
static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) { private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); // allocate the framebuffer if (m->framebuffer == NULL) { // initialize the framebuffer, the framebuffer is mapped once and forever. int err = init_frame_buffer_locked(m); if (err < 0) { return err; } } const uint32_t bufferMask = m->bufferMask; const uint32_t numBuffers = m->numBuffers; const size_t bufferSize = m->finfo.line_length * m->info.yres; if (numBuffers == 1) { // If we have only one buffer, we never use page-flipping. Instead, // we return a regular buffer which will be memcpy'ed to the main // screen when post is called. int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres); return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle); } if (bufferMask >= ((1LU << numBuffers) - 1)) { // We ran out of buffers. return -ENOMEM; } int vaddr = m->framebuffer->base; // find a free slot for (uint32_t i = 0 ; i < numBuffers ; i++) { if ((bufferMask & (1LU << i)) == 0) { m->bufferMask |= (1LU << i); break; } vaddr += bufferSize; } // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr, 0, dup(m->framebuffer->fd), vaddr - m->framebuffer->base); #if GRALLOC_ARM_UMP_MODULE hnd->ump_id = m->framebuffer->ump_id; /* create a backing ump memory handle if the framebuffer is exposed as a secure ID */ if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id) { hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle) { AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id); } } #endif #if GRALLOC_ARM_DMA_BUF_MODULE { #ifdef FBIOGET_DMABUF struct fb_dmabuf_export fb_dma_buf; if (ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf) == 0) { AINF("framebuffer accessed with dma buf (fd 0x%x)\n", (int)fb_dma_buf.fd); hnd->share_fd = fb_dma_buf.fd; } #endif } #endif *pHandle = hnd; return 0; }
static int alloc_device_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride) { if (!pHandle || !pStride) { return -EINVAL; } size_t size; size_t stride; if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12 ) { switch (format) { case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_YV12: stride = GRALLOC_ALIGN(w, 16); size = h * (stride + GRALLOC_ALIGN(stride/2,16)); break; default: return -EINVAL; } } else { int bpp = 0; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: bpp = 4; break; case HAL_PIXEL_FORMAT_RGB_888: bpp = 3; break; case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_RGBA_5551: case HAL_PIXEL_FORMAT_RGBA_4444: bpp = 2; break; default: return -EINVAL; } size_t bpr = GRALLOC_ALIGN(w * bpp, 64); size = bpr * h; stride = bpr / bpp; } int err; #ifndef MALI_600 if (usage & GRALLOC_USAGE_HW_FB) { err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); } else #endif { err = gralloc_alloc_buffer(dev, size, usage, pHandle); } if (err < 0) { return err; } *pStride = stride; return 0; }
int gpu_context_t::alloc_impl(int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride, int bufferSize) { if (!pHandle || !pStride) return -EINVAL; size_t size, alignedw, alignedh; alignedw = ALIGN(w, 32); alignedh = ALIGN(h, 32); int colorFormat, bufferType; getGrallocInformationFromFormat(format, &colorFormat, &bufferType); switch (colorFormat) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: size = alignedw * alignedh * 4; break; case HAL_PIXEL_FORMAT_RGB_888: size = alignedw * alignedh * 3; break; case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_RGBA_5551: case HAL_PIXEL_FORMAT_RGBA_4444: size = alignedw * alignedh * 2; break; // adreno formats case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 size = ALIGN(alignedw*alignedh, 4096); size += ALIGN(2 * ALIGN(w/2, 32) * ALIGN(h/2, 32), 4096); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12 // The chroma plane is subsampled, // but the pitch in bytes is unchanged // The GPU needs 4K alignment, but the video decoder needs 8K alignedw = ALIGN(w, 128); size = ALIGN( alignedw * alignedh, 8192); size += ALIGN( alignedw * ALIGN(h/2, 32), 8192); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP: case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_YV12: if ((w&1) || (h&1)) { LOGE("w or h is odd for the YUV format"); return -EINVAL; } alignedw = ALIGN(w, 16); alignedh = h; size = alignedw*alignedh + (ALIGN(alignedw/2, 16) * (alignedh/2))*2; size = ALIGN(size, 4096); break; default: LOGE("unrecognized pixel format: %d", format); return -EINVAL; } if ((ssize_t)size <= 0) return -EINVAL; size = (bufferSize >= size)? bufferSize : size; // All buffers marked as protected or for external // display need to go to overlay if ((usage & GRALLOC_USAGE_EXTERNAL_DISP) || (usage & GRALLOC_USAGE_PROTECTED)) { bufferType = BUFFER_TYPE_VIDEO; } int err; if (usage & GRALLOC_USAGE_HW_FB) { err = gralloc_alloc_framebuffer(size, usage, pHandle); } else { err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, format, alignedw, alignedh); } if (err < 0) { return err; } *pStride = alignedw; return 0; }