libgralloc-qsd8k: Update the gralloc HAL for Gingerbread
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: I36183bf1fa68e5c8ed80f1efbb5c535a060e0db0
			
			
This commit is contained in:
		
							
								
								
									
										15
									
								
								Android.mk
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Android.mk
									
									
									
									
									
								
							@@ -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)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										506
									
								
								framebuffer.cpp
									
									
									
									
									
								
							
							
						
						
									
										506
									
								
								framebuffer.cpp
									
									
									
									
									
								
							@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								gpu.cpp
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								gpu.cpp
									
									
									
									
									
								
							@@ -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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								gpu.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gpu.h
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								gr.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								gr.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 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								gralloc.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								gralloc.cpp
									
									
									
									
									
								
							@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										138
									
								
								gralloc_priv.h
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								gralloc_priv.h
									
									
									
									
									
								
							@@ -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,19 +137,42 @@ 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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@@ -79,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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										142
									
								
								mapper.cpp
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								mapper.cpp
									
									
									
									
									
								
							@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
@@ -286,7 +289,10 @@ int gralloc_unlock(gralloc_module_t const* module,
 | 
			
		||||
            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);
 | 
			
		||||
        }         
 | 
			
		||||
 | 
			
		||||
        LOGE_IF(err < 0, "cannot flush handle %p (offs=%x len=%x)\n",
 | 
			
		||||
                hnd, hnd->offset, hnd->size);
 | 
			
		||||
@@ -350,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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user