libgralloc-qsd8k: Initial gralloc commit
Update the gralloc HAL to match commit: commit 4d3c9ca6fabf2b0111ef6b567df7d244e124b9c2 Author: Arun Kumar K.R <akkr@codeaurora.org> Date: Fri Dec 17 13:14:58 2010 -0800 libgralloc-qsd8k: Add support for non-aligned width on HDMI While creating overlay channel for HDMI consider the aligned width and set the crop rectangle to the actual width and height. Change-Id: I8858d71bb10b2be4c57edb605b5da680f53051dc
This commit is contained in:
parent
df13c41d1f
commit
a709f0300c
@ -31,8 +31,23 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_CFLAGS:= -DLOG_TAG=\"$(TARGET_BOARD_PLATFORM).gralloc\"
|
||||
|
||||
ifneq (, $(filter msm7625_ffa msm7625_surf msm7627_ffa msm7627_surf msm7627_7x_ffa msm7627_7x_surf, $(QCOM_TARGET_PRODUCT)))
|
||||
LOCAL_CFLAGS += -DTARGET_MSM7x27
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_HAVE_HDMI_OUT),true)
|
||||
LOCAL_CFLAGS += -DHDMI_DUAL_DISPLAY
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../liboverlay
|
||||
LOCAL_SHARED_LIBRARIES += liboverlay
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
|
||||
LOCAL_CFLAGS += -DUSE_ASHMEM
|
||||
endif
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
|
||||
# Build a host library for testing
|
||||
ifeq ($(HOST_OS),linux)
|
||||
include $(CLEAR_VARS)
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -30,6 +31,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/atomic.h>
|
||||
@ -41,12 +43,45 @@
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
#include "gr.h"
|
||||
#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
|
||||
#include <cutils/properties.h>
|
||||
#endif
|
||||
|
||||
#if defined(HDMI_DUAL_DISPLAY)
|
||||
#define AS_1080_RATIO_H (4.25/100) // Default Action Safe vertical limit for 1080p
|
||||
#define AS_1080_RATIO_W (4.25/100) // Default Action Safe horizontal limit for 1080p
|
||||
#define AS_720_RATIO_H (6.0/100) // Default Action Safe vertical limit for 720p
|
||||
#define AS_720_RATIO_W (4.25/100) // Default Action Safe horizontal limit for 720p
|
||||
#define AS_480_RATIO_H (8.0/100) // Default Action Safe vertical limit for 480p
|
||||
#define AS_480_RATIO_W (5.0/100) // Default Action Safe horizontal limit for 480p
|
||||
#define HEIGHT_1080P 1080
|
||||
#define HEIGHT_720P 720
|
||||
#define HEIGHT_480P 480
|
||||
#define EVEN_OUT(x) if (x & 0x0001) {x--;}
|
||||
using overlay::Overlay;
|
||||
/** min of int a, b */
|
||||
static inline int min(int a, int b) {
|
||||
return (a<b) ? a : b;
|
||||
}
|
||||
/** max of int a, 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
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
// numbers of buffers for page flipping
|
||||
#define NUM_BUFFERS 2
|
||||
|
||||
enum {
|
||||
MDDI_PANEL = '1',
|
||||
EBI2_PANEL = '2',
|
||||
LCDC_PANEL = '3',
|
||||
EXT_MDDI_PANEL = '4',
|
||||
TV_PANEL = '5'
|
||||
};
|
||||
|
||||
enum {
|
||||
PAGE_FLIP = 0x00000001,
|
||||
@ -57,6 +92,7 @@ struct fb_context_t {
|
||||
framebuffer_device_t device;
|
||||
};
|
||||
|
||||
static int neworientation;
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
@ -68,9 +104,12 @@ static int fb_setSwapInterval(struct framebuffer_device_t* dev,
|
||||
int interval)
|
||||
{
|
||||
fb_context_t* ctx = (fb_context_t*)dev;
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
|
||||
return -EINVAL;
|
||||
// FIXME: implement fb_setSwapInterval
|
||||
|
||||
m->swapInterval = interval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -89,38 +128,341 @@ static int fb_setUpdateRect(struct framebuffer_device_t* dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *disp_loop(void *ptr)
|
||||
{
|
||||
struct qbuf_t nxtBuf;
|
||||
static int cur_buf=-1;
|
||||
private_module_t *m = reinterpret_cast<private_module_t*>(ptr);
|
||||
|
||||
while (1) {
|
||||
pthread_mutex_lock(&(m->qlock));
|
||||
|
||||
// wait (sleep) while display queue is empty;
|
||||
if (m->disp.isEmpty()) {
|
||||
pthread_cond_wait(&(m->qpost),&(m->qlock));
|
||||
}
|
||||
|
||||
// dequeue next buff to display and lock it
|
||||
nxtBuf = m->disp.getHeadValue();
|
||||
m->disp.pop();
|
||||
pthread_mutex_unlock(&(m->qlock));
|
||||
|
||||
// post buf out to display synchronously
|
||||
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>
|
||||
(nxtBuf.buf);
|
||||
const size_t offset = hnd->base - m->framebuffer->base;
|
||||
m->info.activate = FB_ACTIVATE_VBL;
|
||||
m->info.yoffset = offset / m->finfo.line_length;
|
||||
|
||||
#if defined(HDMI_DUAL_DISPLAY)
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
m->orientation = neworientation;
|
||||
m->currentOffset = offset;
|
||||
pthread_cond_signal(&(m->overlayPost));
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
#endif
|
||||
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
|
||||
LOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed");
|
||||
}
|
||||
|
||||
if (cur_buf == -1) {
|
||||
pthread_mutex_lock(&(m->avail[nxtBuf.idx].lock));
|
||||
m->avail[nxtBuf.idx].is_avail = true;
|
||||
pthread_cond_signal(&(m->avail[nxtBuf.idx].cond));
|
||||
pthread_mutex_unlock(&(m->avail[nxtBuf.idx].lock));
|
||||
} else {
|
||||
pthread_mutex_lock(&(m->avail[cur_buf].lock));
|
||||
m->avail[cur_buf].is_avail = true;
|
||||
pthread_cond_signal(&(m->avail[cur_buf].cond));
|
||||
pthread_mutex_unlock(&(m->avail[cur_buf].lock));
|
||||
|
||||
}
|
||||
cur_buf = nxtBuf.idx;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(HDMI_DUAL_DISPLAY)
|
||||
static void *hdmi_ui_loop(void *ptr)
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
ptr);
|
||||
while (1) {
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
pthread_cond_wait(&(m->overlayPost), &(m->overlayLock));
|
||||
if (m->exitHDMIUILoop) {
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
return NULL;
|
||||
}
|
||||
float asWidthRatio = m->actionsafeWidthRatio/100.0f;
|
||||
float asHeightRatio = m->actionsafeHeightRatio/100.0f;
|
||||
|
||||
if (m->pobjOverlay) {
|
||||
Overlay* pTemp = m->pobjOverlay;
|
||||
if (!m->enableHDMIOutput)
|
||||
pTemp->closeChannel();
|
||||
else if (m->enableHDMIOutput && !m->videoOverlay) {
|
||||
if (!pTemp->isChannelUP()) {
|
||||
int alignedW = ALIGN(m->info.xres, 32);
|
||||
if (pTemp->startChannel(alignedW, m->info.yres,
|
||||
m->fbFormat, 1, false, true)) {
|
||||
pTemp->setFd(m->framebuffer->fd);
|
||||
pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
|
||||
} else
|
||||
pTemp->closeChannel();
|
||||
}
|
||||
|
||||
if (pTemp->isChannelUP()) {
|
||||
int width = pTemp->getFBWidth();
|
||||
int height = pTemp->getFBHeight();
|
||||
int aswidth = width, asheight = height;
|
||||
int final_width = width, final_height = height;
|
||||
int x = 0, y = 0; // Used for calculating normal x,y co-ordinates
|
||||
int x1 = 0, y1 = 0; // Action safe x, y co-ordinates
|
||||
int xx = 0, yy = 0; // Final x, y co-ordinates
|
||||
int fbwidth = m->info.xres, fbheight = m->info.yres;
|
||||
float defaultASWidthRatio = 0.0f, defaultASHeightRatio = 0.0f;
|
||||
if(HEIGHT_1080P == height) {
|
||||
defaultASHeightRatio = AS_1080_RATIO_H;
|
||||
defaultASWidthRatio = AS_1080_RATIO_W;
|
||||
} else if(HEIGHT_720P == height) {
|
||||
defaultASHeightRatio = AS_720_RATIO_H;
|
||||
defaultASWidthRatio = AS_720_RATIO_W;
|
||||
} else if(HEIGHT_480P == height) {
|
||||
defaultASHeightRatio = AS_480_RATIO_H;
|
||||
defaultASWidthRatio = AS_480_RATIO_W;
|
||||
}
|
||||
if(asWidthRatio <= 0.0f)
|
||||
asWidthRatio = defaultASWidthRatio;
|
||||
if(asHeightRatio <= 0.0f)
|
||||
asHeightRatio = defaultASHeightRatio;
|
||||
|
||||
aswidth = (int)((float)width - (float)(width * asWidthRatio));
|
||||
asheight = (int)((float)height - (float)(height * asHeightRatio));
|
||||
x1 = (int)(width * asWidthRatio) / 2;
|
||||
y1 = (int)(height * asHeightRatio) / 2;
|
||||
int rot = m->orientation;
|
||||
if (fbwidth < fbheight) {
|
||||
switch(rot) {
|
||||
// ROT_0
|
||||
case 0:
|
||||
// ROT_180
|
||||
case HAL_TRANSFORM_ROT_180:
|
||||
x = (width - fbwidth) / 2;
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (fbwidth < width)
|
||||
width = fbwidth;
|
||||
if (fbheight < height)
|
||||
height = fbheight;
|
||||
if(rot == HAL_TRANSFORM_ROT_180)
|
||||
rot = OVERLAY_TRANSFORM_ROT_180;
|
||||
else
|
||||
rot = 0;
|
||||
break;
|
||||
// ROT_90
|
||||
case HAL_TRANSFORM_ROT_90:
|
||||
rot = OVERLAY_TRANSFORM_ROT_270;
|
||||
break;
|
||||
// ROT_270
|
||||
case HAL_TRANSFORM_ROT_270:
|
||||
rot = OVERLAY_TRANSFORM_ROT_90;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fbwidth > fbheight) {
|
||||
switch(rot) {
|
||||
// ROT_0
|
||||
case 0:
|
||||
rot = 0;
|
||||
break;
|
||||
// ROT_180
|
||||
case HAL_TRANSFORM_ROT_180:
|
||||
rot = OVERLAY_TRANSFORM_ROT_180;
|
||||
break;
|
||||
// ROT_90
|
||||
case HAL_TRANSFORM_ROT_90:
|
||||
// ROT_270
|
||||
case HAL_TRANSFORM_ROT_270:
|
||||
//Swap width and height
|
||||
int t = fbwidth;
|
||||
fbwidth = fbheight;
|
||||
fbheight = t;
|
||||
x = (width - fbwidth) / 2;
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (fbwidth < width)
|
||||
width = fbwidth;
|
||||
if (fbheight < height)
|
||||
height = fbheight;
|
||||
if(rot == HAL_TRANSFORM_ROT_90)
|
||||
rot = OVERLAY_TRANSFORM_ROT_270;
|
||||
else
|
||||
rot = OVERLAY_TRANSFORM_ROT_90;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pTemp->setParameter(OVERLAY_TRANSFORM,
|
||||
rot);
|
||||
// Calculate the interection of final destination parameters
|
||||
// Intersection of Action Safe rect and the orig rect will give the final dest rect
|
||||
xx = max(x1, x);
|
||||
yy = max(y1, y);
|
||||
final_width = min((x1+aswidth), (x+width))- xx;
|
||||
final_height = min((y1+asheight), (y+height))- yy;
|
||||
EVEN_OUT(xx);
|
||||
EVEN_OUT(yy);
|
||||
EVEN_OUT(final_width);
|
||||
EVEN_OUT(final_height);
|
||||
pTemp->setPosition(xx, yy, final_width, final_height);
|
||||
pTemp->queueBuffer(m->currentOffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
pTemp->closeChannel();
|
||||
}
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
Overlay* pTemp = m->pobjOverlay;
|
||||
if (started && pTemp) {
|
||||
pTemp->closeChannel();
|
||||
m->videoOverlay = true;
|
||||
pthread_cond_signal(&(m->overlayPost));
|
||||
}
|
||||
else {
|
||||
m->videoOverlay = false;
|
||||
pthread_cond_signal(&(m->overlayPost));
|
||||
}
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int enable)
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
Overlay* pTemp = m->pobjOverlay;
|
||||
if (!enable && pTemp)
|
||||
pTemp->closeChannel();
|
||||
m->enableHDMIOutput = enable;
|
||||
pthread_cond_signal(&(m->overlayPost));
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_setActionSafeWidthRatio(struct framebuffer_device_t* dev, float asWidthRatio)
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
m->actionsafeWidthRatio = asWidthRatio;
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_setActionSafeHeightRatio(struct framebuffer_device_t* dev, float asHeightRatio)
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
m->actionsafeHeightRatio = asHeightRatio;
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
return 0;
|
||||
}
|
||||
static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientation)
|
||||
{
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
neworientation = orientation;
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
|
||||
{
|
||||
if (private_handle_t::validate(buffer) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
int nxtIdx;
|
||||
bool reuse;
|
||||
struct qbuf_t qb;
|
||||
fb_context_t* ctx = (fb_context_t*)dev;
|
||||
|
||||
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
|
||||
if (m->currentBuffer) {
|
||||
m->base.unlock(&m->base, m->currentBuffer);
|
||||
m->currentBuffer = 0;
|
||||
}
|
||||
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
|
||||
|
||||
m->base.lock(&m->base, buffer,
|
||||
private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
|
||||
0, 0, m->info.xres, m->info.yres, NULL);
|
||||
reuse = false;
|
||||
nxtIdx = (m->currentIdx + 1) % NUM_BUFFERS;
|
||||
|
||||
const size_t offset = hnd->base - m->framebuffer->base;
|
||||
m->info.activate = FB_ACTIVATE_VBL;
|
||||
m->info.yoffset = offset / m->finfo.line_length;
|
||||
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
|
||||
LOGE("FBIOPUT_VSCREENINFO failed");
|
||||
m->base.unlock(&m->base, buffer);
|
||||
return -errno;
|
||||
if (m->swapInterval == 0) {
|
||||
// if SwapInterval = 0 and no buffers available then reuse
|
||||
// current buf for next rendering so don't post new buffer
|
||||
if (pthread_mutex_trylock(&(m->avail[nxtIdx].lock))) {
|
||||
reuse = true;
|
||||
} else {
|
||||
if (! m->avail[nxtIdx].is_avail)
|
||||
reuse = true;
|
||||
pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
|
||||
}
|
||||
}
|
||||
m->currentBuffer = buffer;
|
||||
|
||||
|
||||
if(!reuse){
|
||||
// unlock previous ("current") Buffer and lock the new buffer
|
||||
m->base.lock(&m->base, buffer,
|
||||
private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
|
||||
0,0, m->info.xres, m->info.yres, NULL);
|
||||
|
||||
// post/queue the new buffer
|
||||
pthread_mutex_lock(&(m->avail[nxtIdx].lock));
|
||||
m->avail[nxtIdx].is_avail = false;
|
||||
pthread_mutex_unlock(&(m->avail[nxtIdx].lock));
|
||||
|
||||
qb.idx = nxtIdx;
|
||||
qb.buf = buffer;
|
||||
pthread_mutex_lock(&(m->qlock));
|
||||
m->disp.push(qb);
|
||||
pthread_cond_signal(&(m->qpost));
|
||||
pthread_mutex_unlock(&(m->qlock));
|
||||
|
||||
// LCDC: after new buffer grabbed by MDP can unlock previous
|
||||
// (current) buffer
|
||||
if (m->currentBuffer) {
|
||||
if (m->swapInterval != 0) {
|
||||
pthread_mutex_lock(&(m->avail[m->currentIdx].lock));
|
||||
if (! m->avail[m->currentIdx].is_avail) {
|
||||
pthread_cond_wait(&(m->avail[m->currentIdx].cond),
|
||||
&(m->avail[m->currentIdx].lock));
|
||||
m->avail[m->currentIdx].is_avail = true;
|
||||
}
|
||||
pthread_mutex_unlock(&(m->avail[m->currentIdx].lock));
|
||||
}
|
||||
m->base.unlock(&m->base, m->currentBuffer);
|
||||
}
|
||||
m->currentBuffer = buffer;
|
||||
m->currentIdx = nxtIdx;
|
||||
} else {
|
||||
if (m->currentBuffer)
|
||||
m->base.unlock(&m->base, m->currentBuffer);
|
||||
m->base.lock(&m->base, buffer,
|
||||
private_module_t::PRIV_USAGE_LOCKED_FOR_POST,
|
||||
0,0, m->info.xres, m->info.yres, NULL);
|
||||
m->currentBuffer = buffer;
|
||||
}
|
||||
|
||||
} else {
|
||||
void* fb_vaddr;
|
||||
void* buffer_vaddr;
|
||||
@ -206,28 +548,45 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
* big-endian byte order if bits_per_pixel is greater than 8.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Explicitly request RGBA_8888
|
||||
*/
|
||||
info.bits_per_pixel = 32;
|
||||
info.red.offset = 24;
|
||||
info.red.length = 8;
|
||||
info.green.offset = 16;
|
||||
info.green.length = 8;
|
||||
info.blue.offset = 8;
|
||||
info.blue.length = 8;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 0;
|
||||
|
||||
/* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
|
||||
* not use the MDP for composition (i.e. hw composition == 0), ask for
|
||||
* RGBA instead of RGBX. */
|
||||
char property[PROPERTY_VALUE_MAX];
|
||||
if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
|
||||
if(info.bits_per_pixel == 32) {
|
||||
/*
|
||||
* Explicitly request RGBA_8888
|
||||
*/
|
||||
info.bits_per_pixel = 32;
|
||||
info.red.offset = 24;
|
||||
info.red.length = 8;
|
||||
info.green.offset = 16;
|
||||
info.green.length = 8;
|
||||
info.blue.offset = 8;
|
||||
info.blue.length = 8;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 8;
|
||||
|
||||
/* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we do
|
||||
* not use the MDP for composition (i.e. hw composition == 0), ask for
|
||||
* RGBA instead of RGBX. */
|
||||
char property[PROPERTY_VALUE_MAX];
|
||||
if (property_get("debug.sf.hw", property, NULL) > 0 && atoi(property) == 0)
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else if(property_get("debug.composition.type", property, NULL) > 0 && (strncmp(property, "mdp", 3) == 0))
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
|
||||
else
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
|
||||
} else {
|
||||
/*
|
||||
* Explicitly request 5/6/5
|
||||
*/
|
||||
info.bits_per_pixel = 16;
|
||||
info.red.offset = 11;
|
||||
info.red.length = 5;
|
||||
info.green.offset = 5;
|
||||
info.green.length = 6;
|
||||
info.blue.offset = 0;
|
||||
info.blue.length = 5;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 0;
|
||||
module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
|
||||
}
|
||||
/*
|
||||
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
|
||||
*/
|
||||
@ -320,6 +679,38 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
module->ydpi = ydpi;
|
||||
module->fps = fps;
|
||||
|
||||
#ifdef NO_SURFACEFLINGER_SWAPINTERVAL
|
||||
char pval[PROPERTY_VALUE_MAX];
|
||||
property_get("debug.gr.swapinterval", pval, "1");
|
||||
module->swapInterval = atoi(pval);
|
||||
if (module->swapInterval < private_module_t::PRIV_MIN_SWAP_INTERVAL ||
|
||||
module->swapInterval > private_module_t::PRIV_MAX_SWAP_INTERVAL) {
|
||||
module->swapInterval = 1;
|
||||
LOGW("Out of range (%d to %d) value for debug.gr.swapinterval, using 1",
|
||||
private_module_t::PRIV_MIN_SWAP_INTERVAL,
|
||||
private_module_t::PRIV_MAX_SWAP_INTERVAL);
|
||||
}
|
||||
|
||||
#else
|
||||
/* when surfaceflinger supports swapInterval then can just do this */
|
||||
module->swapInterval = 1;
|
||||
#endif
|
||||
|
||||
module->currentIdx = -1;
|
||||
pthread_cond_init(&(module->qpost), NULL);
|
||||
pthread_mutex_init(&(module->qlock), NULL);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
pthread_mutex_init(&(module->avail[i].lock), NULL);
|
||||
pthread_cond_init(&(module->avail[i].cond), NULL);
|
||||
module->avail[i].is_avail = true;
|
||||
}
|
||||
|
||||
/* create display update thread */
|
||||
pthread_t thread1;
|
||||
if (pthread_create(&thread1, NULL, &disp_loop, (void *) module)) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* map the framebuffer
|
||||
*/
|
||||
@ -339,6 +730,18 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
}
|
||||
module->framebuffer->base = intptr_t(vaddr);
|
||||
memset(vaddr, 0, fbSize);
|
||||
|
||||
#if defined(HDMI_DUAL_DISPLAY)
|
||||
/* Overlay for HDMI*/
|
||||
pthread_mutex_init(&(module->overlayLock), NULL);
|
||||
pthread_cond_init(&(module->overlayPost), NULL);
|
||||
module->pobjOverlay = new Overlay();
|
||||
module->currentOffset = 0;
|
||||
module->exitHDMIUILoop = false;
|
||||
pthread_t hdmiUIThread;
|
||||
pthread_create(&hdmiUIThread, NULL, &hdmi_ui_loop, (void *) module);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -355,6 +758,14 @@ static int mapFrameBuffer(struct private_module_t* module)
|
||||
static int fb_close(struct hw_device_t *dev)
|
||||
{
|
||||
fb_context_t* ctx = (fb_context_t*)dev;
|
||||
#if defined(HDMI_DUAL_DISPLAY)
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
ctx->device.common.module);
|
||||
pthread_mutex_lock(&m->overlayLock);
|
||||
m->exitHDMIUILoop = true;
|
||||
pthread_cond_signal(&(m->overlayPost));
|
||||
pthread_mutex_unlock(&m->overlayLock);
|
||||
#endif
|
||||
if (ctx) {
|
||||
free(ctx);
|
||||
}
|
||||
@ -384,6 +795,13 @@ int fb_device_open(hw_module_t const* module, const char* name,
|
||||
dev->device.post = fb_post;
|
||||
dev->device.setUpdateRect = 0;
|
||||
dev->device.compositionComplete = fb_compositionComplete;
|
||||
#if defined(HDMI_DUAL_DISPLAY)
|
||||
dev->device.orientationChanged = fb_orientationChanged;
|
||||
dev->device.videoOverlayStarted = fb_videoOverlayStarted;
|
||||
dev->device.enableHDMIOutput = fb_enableHDMIOutput;
|
||||
dev->device.setActionSafeWidthRatio = fb_setActionSafeWidthRatio;
|
||||
dev->device.setActionSafeHeightRatio = fb_setActionSafeHeightRatio;
|
||||
#endif
|
||||
|
||||
private_module_t* m = (private_module_t*)module;
|
||||
status = mapFrameBuffer(m);
|
||||
@ -397,8 +815,8 @@ int fb_device_open(hw_module_t const* module, const char* name,
|
||||
const_cast<float&>(dev->device.xdpi) = m->xdpi;
|
||||
const_cast<float&>(dev->device.ydpi) = m->ydpi;
|
||||
const_cast<float&>(dev->device.fps) = m->fps;
|
||||
const_cast<int&>(dev->device.minSwapInterval) = 1;
|
||||
const_cast<int&>(dev->device.maxSwapInterval) = 1;
|
||||
const_cast<int&>(dev->device.minSwapInterval) = private_module_t::PRIV_MIN_SWAP_INTERVAL;
|
||||
const_cast<int&>(dev->device.maxSwapInterval) = private_module_t::PRIV_MAX_SWAP_INTERVAL;
|
||||
|
||||
if (m->finfo.reserved[0] == 0x5444 &&
|
||||
m->finfo.reserved[1] == 0x5055) {
|
||||
|
@ -79,7 +79,7 @@ int gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage,
|
||||
|
||||
// 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), size,
|
||||
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);
|
||||
|
||||
@ -110,6 +110,46 @@ int gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage,
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpu_context_t::alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
|
||||
int* pOffset, int* pFd)
|
||||
{
|
||||
int err = 0;
|
||||
int fd = -1;
|
||||
void* base = 0;
|
||||
int offset = 0;
|
||||
|
||||
char name[ASHMEM_NAME_LEN];
|
||||
snprintf(name, ASHMEM_NAME_LEN, "gralloc-buffer-%x", postfix);
|
||||
int prot = PROT_READ | PROT_WRITE;
|
||||
fd = ashmem_create_region(name, size);
|
||||
if (fd < 0) {
|
||||
LOGE("couldn't create ashmem (%s)", strerror(errno));
|
||||
err = -errno;
|
||||
} else {
|
||||
if (ashmem_set_prot_region(fd, prot) < 0) {
|
||||
LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)",
|
||||
fd, prot, strerror(errno));
|
||||
close(fd);
|
||||
err = -errno;
|
||||
} else {
|
||||
base = mmap(0, size, prot, MAP_SHARED|MAP_POPULATE|MAP_LOCKED, fd, 0);
|
||||
if (base == MAP_FAILED) {
|
||||
LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)",
|
||||
fd, size, prot, strerror(errno));
|
||||
close(fd);
|
||||
err = -errno;
|
||||
} else {
|
||||
memset((char*)base + offset, 0, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(err == 0) {
|
||||
*pFd = fd;
|
||||
*pBase = base;
|
||||
*pOffset = offset;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle)
|
||||
{
|
||||
@ -123,7 +163,7 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t*
|
||||
int lockState = 0;
|
||||
|
||||
size = roundUpToPageSize(size);
|
||||
|
||||
#ifndef USE_ASHMEM
|
||||
if (usage & GRALLOC_USAGE_HW_TEXTURE) {
|
||||
// enable pmem in that case, so our software GL can fallback to
|
||||
// the copybit module.
|
||||
@ -133,15 +173,25 @@ int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t*
|
||||
if (usage & GRALLOC_USAGE_HW_2D) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
|
||||
#else
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_PMEM){
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
#endif
|
||||
if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
|
||||
flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
|
||||
}
|
||||
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
|
||||
|
||||
if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
|
||||
if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 &&
|
||||
(flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) {
|
||||
flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
|
||||
err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
|
||||
if(err >= 0)
|
||||
lockState |= private_handle_t::LOCK_STATE_MAPPED;
|
||||
}
|
||||
else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
|
||||
(flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
|
||||
|
||||
PmemAllocator* pma = 0;
|
||||
|
@ -71,6 +71,8 @@ class gpu_context_t : public alloc_device_t {
|
||||
Deps& deps;
|
||||
PmemAllocator& pmemAllocator;
|
||||
PmemAllocator& pmemAdspAllocator;
|
||||
int alloc_ashmem_buffer(size_t size, unsigned int postfix, void** pBase,
|
||||
int* pOffset, int* pFd);
|
||||
};
|
||||
|
||||
#endif // GRALLOC_QSD8K_GPU_H
|
||||
|
@ -40,9 +40,15 @@ inline size_t roundUpToPageSize(size_t x) {
|
||||
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-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);
|
||||
int decideBufferHandlingMechanism(int format, const char *compositionUsed,
|
||||
int hasBlitEngine, int *needConversion,
|
||||
int *useBufferDirectly);
|
||||
/*****************************************************************************/
|
||||
|
||||
class Locker {
|
||||
|
@ -65,11 +65,20 @@ class PmemAllocatorDepsDeviceImpl : public PmemUserspaceAllocator::Deps,
|
||||
public PmemKernelAllocator::Deps {
|
||||
|
||||
virtual size_t getPmemTotalSize(int fd, size_t* size) {
|
||||
int err = 0;
|
||||
#ifndef TARGET_MSM7x27
|
||||
pmem_region region;
|
||||
int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®ion);
|
||||
err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®ion);
|
||||
if (err == 0) {
|
||||
*size = region.len;
|
||||
}
|
||||
#else
|
||||
#ifdef USE_ASHMEM
|
||||
*size = m->info.xres * m->info.yres * 2 * 2;
|
||||
#else
|
||||
*size = 23<<20; //23MB for 7x27
|
||||
#endif
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
143
libgralloc-qsd8k/gralloc_priv.h
Normal file → Executable file
143
libgralloc-qsd8k/gralloc_priv.h
Normal file → Executable file
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -29,12 +30,98 @@
|
||||
|
||||
#include <linux/fb.h>
|
||||
|
||||
#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
|
||||
#include "overlayLib.h"
|
||||
using namespace overlay;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
/* gralloc usage bit indicating a pmem_adsp allocation should be used */
|
||||
GRALLOC_USAGE_PRIVATE_PMEM_ADSP = GRALLOC_USAGE_PRIVATE_0,
|
||||
GRALLOC_USAGE_PRIVATE_PMEM = GRALLOC_USAGE_PRIVATE_1,
|
||||
};
|
||||
|
||||
#define NUM_BUFFERS 2
|
||||
#define NO_SURFACEFLINGER_SWAPINTERVAL
|
||||
#define INTERLACE_MASK 0x80
|
||||
/*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
template <class T>
|
||||
struct Node
|
||||
{
|
||||
T data;
|
||||
Node<T> *next;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class Queue
|
||||
{
|
||||
public:
|
||||
Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
|
||||
~Queue()
|
||||
{
|
||||
clear();
|
||||
delete dummy;
|
||||
}
|
||||
void push(const T& item) //add an item to the back of the queue
|
||||
{
|
||||
if(len != 0) { //if the queue is not empty
|
||||
back->next = new Node<T>; //create a new node
|
||||
back = back->next; //set the new node as the back node
|
||||
back->data = item;
|
||||
back->next = NULL;
|
||||
} else {
|
||||
back = new Node<T>;
|
||||
back->data = item;
|
||||
back->next = NULL;
|
||||
front = back;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
void pop() //remove the first item from the queue
|
||||
{
|
||||
if (isEmpty())
|
||||
return; //if the queue is empty, no node to dequeue
|
||||
T item = front->data;
|
||||
Node<T> *tmp = front;
|
||||
front = front->next;
|
||||
delete tmp;
|
||||
if(front == NULL) //if the queue is empty, update the back pointer
|
||||
back = NULL;
|
||||
len--;
|
||||
return;
|
||||
}
|
||||
T& getHeadValue() const //return the value of the first item in the queue
|
||||
{ //without modification to the structure
|
||||
if (isEmpty()) {
|
||||
LOGE("Error can't get head of empty queue");
|
||||
return *dummy;
|
||||
}
|
||||
return front->data;
|
||||
}
|
||||
|
||||
bool isEmpty() const //returns true if no elements are in the queue
|
||||
{
|
||||
return (front == NULL);
|
||||
}
|
||||
|
||||
size_t size() const //returns the amount of elements in the queue
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
private:
|
||||
Node<T> *front;
|
||||
Node<T> *back;
|
||||
size_t len;
|
||||
void clear()
|
||||
{
|
||||
while (!isEmpty())
|
||||
pop();
|
||||
}
|
||||
T *dummy;
|
||||
};
|
||||
#endif
|
||||
|
||||
enum {
|
||||
/* OEM specific HAL formats */
|
||||
@ -50,7 +137,21 @@ enum {
|
||||
HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x10A,
|
||||
HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x10B,
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP_INTERLACE = 0x10C,
|
||||
HAL_PIXEL_FORMAT_R_8 = 0x10D,
|
||||
HAL_PIXEL_FORMAT_RG_88 = 0x10E,
|
||||
HAL_PIXEL_FORMAT_INTERLACE = 0x180,
|
||||
|
||||
};
|
||||
|
||||
/* possible formats for 3D content*/
|
||||
enum {
|
||||
HAL_NO_3D = 0x00,
|
||||
HAL_3D_IN_LR_SIDE = 0x10000,
|
||||
HAL_3D_IN_LR_TOP = 0x20000,
|
||||
HAL_3D_IN_LR_INTERLEAVE = 0x40000,
|
||||
HAL_3D_OUT_LR_SIDE = 0x1,
|
||||
HAL_3D_OUT_LR_TOP = 0x2,
|
||||
HAL_3D_OUT_LR_INTERLEAVE = 0x4
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -59,6 +160,19 @@ struct private_module_t;
|
||||
struct private_handle_t;
|
||||
struct PmemAllocator;
|
||||
|
||||
struct qbuf_t {
|
||||
buffer_handle_t buf;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct avail_t {
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
#ifdef __cplusplus
|
||||
bool is_avail;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct private_module_t {
|
||||
gralloc_module_t base;
|
||||
|
||||
@ -75,11 +189,33 @@ struct private_module_t {
|
||||
float xdpi;
|
||||
float ydpi;
|
||||
float fps;
|
||||
|
||||
int swapInterval;
|
||||
#ifdef __cplusplus
|
||||
Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
|
||||
#endif
|
||||
int currentIdx;
|
||||
struct avail_t avail[NUM_BUFFERS];
|
||||
pthread_mutex_t qlock;
|
||||
pthread_cond_t qpost;
|
||||
|
||||
enum {
|
||||
// flag to indicate we'll post this buffer
|
||||
PRIV_USAGE_LOCKED_FOR_POST = 0x80000000
|
||||
PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
|
||||
PRIV_MIN_SWAP_INTERVAL = 0,
|
||||
PRIV_MAX_SWAP_INTERVAL = 1,
|
||||
};
|
||||
#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
|
||||
Overlay* pobjOverlay;
|
||||
int orientation;
|
||||
bool videoOverlay;
|
||||
uint32_t currentOffset;
|
||||
bool enableHDMIOutput;
|
||||
bool exitHDMIUILoop;
|
||||
float actionsafeWidthRatio;
|
||||
float actionsafeHeightRatio;
|
||||
pthread_mutex_t overlayLock;
|
||||
pthread_cond_t overlayPost;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -96,6 +232,7 @@ struct private_handle_t {
|
||||
PRIV_FLAGS_USES_PMEM = 0x00000002,
|
||||
PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
|
||||
PRIV_FLAGS_NEEDS_FLUSH = 0x00000008,
|
||||
PRIV_FLAGS_USES_ASHMEM = 0x00000010,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
151
libgralloc-qsd8k/mapper.cpp
Normal file → Executable file
151
libgralloc-qsd8k/mapper.cpp
Normal file → Executable file
@ -25,9 +25,11 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/ashmem.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/atomic.h>
|
||||
#include <cutils/ashmem.h>
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/gralloc.h>
|
||||
@ -35,7 +37,7 @@
|
||||
#include <linux/android_pmem.h>
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
|
||||
#include "gr.h"
|
||||
|
||||
// we need this for now because pmem cannot mmap at an offset
|
||||
#define PMEM_HACK 1
|
||||
@ -55,13 +57,19 @@ static int gralloc_map(gralloc_module_t const* module,
|
||||
void** vaddr)
|
||||
{
|
||||
private_handle_t* hnd = (private_handle_t*)handle;
|
||||
void *mappedAddress;
|
||||
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
|
||||
size_t size = hnd->size;
|
||||
#if PMEM_HACK
|
||||
size += hnd->offset;
|
||||
#endif
|
||||
void* mappedAddress = mmap(0, size,
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM) {
|
||||
mappedAddress = mmap(0, size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED | MAP_POPULATE, hnd->fd, 0);
|
||||
} else {
|
||||
mappedAddress = mmap(0, size,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);
|
||||
}
|
||||
if (mappedAddress == MAP_FAILED) {
|
||||
LOGE("Could not mmap handle %p, fd=%d (%s)",
|
||||
handle, hnd->fd, strerror(errno));
|
||||
@ -171,8 +179,8 @@ int terminateBuffer(gralloc_module_t const* module,
|
||||
|
||||
if (hnd->lockState & private_handle_t::LOCK_STATE_MAPPED) {
|
||||
// this buffer was mapped, unmap it now
|
||||
if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) ||
|
||||
(hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP)) {
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM ||
|
||||
hnd->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM) {
|
||||
if (hnd->pid != getpid()) {
|
||||
// ... unless it's a "master" pmem buffer, that is a buffer
|
||||
// mapped in the process it's been allocated.
|
||||
@ -239,12 +247,7 @@ int gralloc_lock(gralloc_module_t const* module,
|
||||
// if requesting sw write for non-framebuffer handles, flag for
|
||||
// flushing at unlock
|
||||
|
||||
const uint32_t pmemMask =
|
||||
private_handle_t::PRIV_FLAGS_USES_PMEM |
|
||||
private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
|
||||
|
||||
if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) &&
|
||||
(hnd->flags & pmemMask) &&
|
||||
!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
|
||||
hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
|
||||
}
|
||||
@ -279,12 +282,18 @@ int gralloc_unlock(gralloc_module_t const* module,
|
||||
int32_t current_value, new_value;
|
||||
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
|
||||
struct pmem_region region;
|
||||
int err;
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_PMEM) {
|
||||
struct pmem_addr pmem_addr;
|
||||
pmem_addr.vaddr = hnd->base;
|
||||
pmem_addr.offset = hnd->offset;
|
||||
pmem_addr.length = hnd->size;
|
||||
err = ioctl( hnd->fd, PMEM_CLEAN_CACHES, &pmem_addr);
|
||||
} else if ((hnd->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)) {
|
||||
unsigned long addr = hnd->base + hnd->offset;
|
||||
err = ioctl(hnd->fd, ASHMEM_CACHE_CLEAN_RANGE, NULL);
|
||||
}
|
||||
|
||||
region.offset = hnd->offset;
|
||||
region.len = hnd->size;
|
||||
err = ioctl(hnd->fd, PMEM_CACHE_FLUSH, ®ion);
|
||||
LOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x)\n",
|
||||
hnd, hnd->offset, hnd->size);
|
||||
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
|
||||
@ -347,12 +356,128 @@ int gralloc_perform(struct gralloc_module_t const* module,
|
||||
hnd->offset = offset;
|
||||
hnd->base = intptr_t(base) + offset;
|
||||
hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;
|
||||
hnd->gpuaddr = 0;
|
||||
*handle = (native_handle_t *)hnd;
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
case GRALLOC_MODULE_PERFORM_DECIDE_PUSH_BUFFER_HANDLING: {
|
||||
int format = va_arg(args, int);
|
||||
int width = va_arg(args, int);
|
||||
int height = va_arg(args, int);
|
||||
char *compositionUsed = va_arg(args, char*);
|
||||
int hasBlitEngine = va_arg(args, int);
|
||||
int *needConversion = va_arg(args, int*);
|
||||
int *useBufferDirectly = va_arg(args, int*);
|
||||
size_t *size = va_arg(args, size_t*);
|
||||
*size = calculateBufferSize(width, height, format);
|
||||
int conversion = 0;
|
||||
int direct = 0;
|
||||
res = decideBufferHandlingMechanism(format, compositionUsed, hasBlitEngine,
|
||||
needConversion, useBufferDirectly);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
return res;
|
||||
}
|
||||
|
||||
int decideBufferHandlingMechanism(int format, const char *compositionUsed, int hasBlitEngine,
|
||||
int *needConversion, int *useBufferDirectly)
|
||||
{
|
||||
*needConversion = FALSE;
|
||||
*useBufferDirectly = FALSE;
|
||||
if(compositionUsed == NULL) {
|
||||
LOGE("null pointer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(format == HAL_PIXEL_FORMAT_RGB_565) {
|
||||
// Software video renderer gives the output in RGB565 format.
|
||||
// This can be handled by all compositors
|
||||
*needConversion = FALSE;
|
||||
*useBufferDirectly = TRUE;
|
||||
} else if(strncmp(compositionUsed, "cpu", 3) == 0){
|
||||
*needConversion = FALSE;
|
||||
*useBufferDirectly = FALSE;
|
||||
} else if(strncmp(compositionUsed, "gpu", 3) == 0) {
|
||||
if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED
|
||||
|| format == HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO) {
|
||||
*needConversion = FALSE;
|
||||
*useBufferDirectly = TRUE;
|
||||
} else if(hasBlitEngine) {
|
||||
*needConversion = TRUE;
|
||||
*useBufferDirectly = FALSE;
|
||||
}
|
||||
} else if ((strncmp(compositionUsed, "mdp", 3) == 0) ||
|
||||
(strncmp(compositionUsed, "c2d", 3) == 0)){
|
||||
if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP ||
|
||||
format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
|
||||
*needConversion = FALSE;
|
||||
*useBufferDirectly = TRUE;
|
||||
} else if((strncmp(compositionUsed, "c2d", 3) == 0) &&
|
||||
format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
|
||||
*needConversion = FALSE;
|
||||
*useBufferDirectly = TRUE;
|
||||
} else if(hasBlitEngine) {
|
||||
*needConversion = TRUE;
|
||||
*useBufferDirectly = FALSE;
|
||||
}
|
||||
} else {
|
||||
LOGE("Invalid composition type %s", compositionUsed);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t calculateBufferSize(int width, int height, int format)
|
||||
{
|
||||
if(!width || !height)
|
||||
return 0;
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
|
||||
int aligned_height = (height + 31) & ~31;
|
||||
int pitch = (width + 127) & ~127;
|
||||
size = pitch * aligned_height;
|
||||
size = (size + 8191) & ~8191;
|
||||
int secondPlaneOffset = size;
|
||||
|
||||
aligned_height = ((height >> 1) + 31) & ~31;
|
||||
size += pitch * aligned_height;
|
||||
size = (size + 8191) & ~8191;
|
||||
break;
|
||||
}
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: {
|
||||
int aligned_height = (height + 31) & ~31;
|
||||
int pitch = (width + 31) & ~31;
|
||||
size = pitch * aligned_height;
|
||||
size = (size + 4095) & ~4095;
|
||||
int secondPlaneOffset = size;
|
||||
|
||||
pitch = 2 * (((width >> 1) + 31) & ~31);
|
||||
aligned_height = ((height >> 1) + 31) & ~31;
|
||||
size += pitch * aligned_height;
|
||||
size = (size + 4095) & ~4095;
|
||||
break;
|
||||
}
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP: {
|
||||
/* Camera and video YUV 420 semi-planar buffers are allocated with
|
||||
size equal to w * h * 1.5 */
|
||||
int aligned_width = (width + 15) & ~15;
|
||||
int aligned_chroma_width = ((width/2) + 15) & ~15;
|
||||
size = (aligned_width * height) + ((aligned_chroma_width * height/2) *2);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
@ -181,6 +181,7 @@ int PmemUserspaceAllocator::alloc_pmem_buffer(size_t size, int usage,
|
||||
} else {
|
||||
LOGV("%s: mapped fd %d at offset %d, size %d", pmemdev, fd, offset, size);
|
||||
memset((char*)base + offset, 0, size);
|
||||
//cacheflush(intptr_t(base) + offset, intptr_t(base) + offset + size, 0);
|
||||
*pBase = base;
|
||||
*pOffset = offset;
|
||||
*pFd = fd;
|
||||
|
Loading…
x
Reference in New Issue
Block a user