diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp index fbe2113..b531afc 100644 --- a/libgralloc/alloc_controller.cpp +++ b/libgralloc/alloc_controller.cpp @@ -36,6 +36,7 @@ #include "ionalloc.h" #include "pmemalloc.h" #include "ashmemalloc.h" +#include "gr.h" using namespace gralloc; using android::sp; @@ -323,4 +324,66 @@ sp PmemAshmemController::getAllocator(int flags) return memalloc; } +size_t getBufferSizeAndDimensions(int width, int height, int format, + int& alignedw, int &alignedh) +{ + size_t size; + alignedw = ALIGN(width, 32); + alignedh = ALIGN(height, 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(width/2, 32) * ALIGN(height/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(width, 128); + size = ALIGN( alignedw * alignedh, 8192); + size += ALIGN( alignedw * ALIGN(height/2, 32), 8192); + break; + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YV12: + if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) { + LOGE("w or h is odd for the YV12 format"); + return -EINVAL; + } + alignedw = ALIGN(width, 16); + alignedh = height; + if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) { + // The encoder requires a 2K aligned chroma offset. + size = ALIGN(alignedw*alignedh, 2048) + + (ALIGN(alignedw/2, 16) * (alignedh/2))*2; + } else { + size = alignedw*alignedh + + (ALIGN(alignedw/2, 16) * (alignedh/2))*2; + } + size = ALIGN(size, 4096); + break; + + default: + LOGE("unrecognized pixel format: %d", format); + return -EINVAL; + } + + return size; +} diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp index 517fc96..c2ec390 100644 --- a/libgralloc/framebuffer.cpp +++ b/libgralloc/framebuffer.cpp @@ -73,10 +73,6 @@ static inline int min(int a, int b) { static inline int max(int a, int b) { return (a>b) ? a : b; } -/** align */ -static inline size_t ALIGN(size_t x, size_t align) { - return (x + align-1) & ~(align-1); -} #endif char framebufferStateName[] = {'S', 'R', 'A'}; diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp index 654b1d2..679cf37 100755 --- a/libgralloc/gpu.cpp +++ b/libgralloc/gpu.cpp @@ -178,10 +178,6 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, return err; } -static inline size_t ALIGN(size_t x, size_t align) { - return (x + align-1) & ~(align-1); -} - void gpu_context_t::getGrallocInformationFromFormat(int inputFormat, int *colorFormat, int *bufferType) @@ -213,69 +209,14 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage, if (!pHandle || !pStride) return -EINVAL; - size_t size, alignedw, alignedh; - - alignedw = ALIGN(w, 32); - alignedh = ALIGN(h, 32); + size_t size; + int alignedw, alignedh; 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_NV12_ENCODEABLE: - case HAL_PIXEL_FORMAT_YCbCr_420_SP: - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YV12: - if ((format == HAL_PIXEL_FORMAT_YV12) && ((w&1) || (h&1))) { - LOGE("w or h is odd for the YV12 format"); - return -EINVAL; - } - alignedw = ALIGN(w, 16); - alignedh = h; - if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == colorFormat) { - // The encoder requires a 2K aligned chroma offset. - size = ALIGN(alignedw*alignedh, 2048) + - (ALIGN(alignedw/2, 16) * (alignedh/2))*2; - } else { - size = alignedw*alignedh + - (ALIGN(alignedw/2, 16) * (alignedh/2))*2; - } - size = ALIGN(size, 4096); - break; - - default: - LOGE("unrecognized pixel format: %d", format); - return -EINVAL; - } + size = getBufferSizeAndDimensions(w, h, colorFormat, alignedw, alignedh); if ((ssize_t)size <= 0) return -EINVAL; - size = (bufferSize >= size)? bufferSize : size; // All buffers marked as protected or for external diff --git a/libgralloc/gr.h b/libgralloc/gr.h index 034a546..12efa7c 100644 --- a/libgralloc/gr.h +++ b/libgralloc/gr.h @@ -41,12 +41,18 @@ inline size_t roundUpToPageSize(size_t x) { return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); } +inline size_t ALIGN(size_t x, size_t align) { + return (x + align-1) & ~(align-1); +} + #define FALSE 0 #define TRUE 1 int mapFrameBufferLocked(struct private_module_t* module); int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd); -size_t calculateBufferSize(int width, int height, int format); +size_t getBufferSizeAndDimensions(int width, int height, int format, + int& alignedw, int &alignedh); + int decideBufferHandlingMechanism(int format, const char *compositionUsed, int hasBlitEngine, int *needConversion, int *useBufferDirectly);