libqdutils: Add copybit support to qdutils
- Introduce cbutils for copybit utilities - Don't use qcomuiclearregion if GPU is used - Check for qcom composition types updating FB - Dont show YUV information to copybit - Fallback to GPU in the presence of SKIP layers This change adds support in qdutils to check for FB updating composition type. Change-Id: I200d3798a27836a51f4b2e6c79cdd9d8b155fad8
This commit is contained in:
		
				
					committed by
					
						
						Andrew Sutherland
					
				
			
			
				
	
			
			
			
						parent
						
							db76cc05a0
						
					
				
				
					commit
					cfb095ef61
				
			@@ -34,6 +34,7 @@
 | 
			
		||||
#include "hwc_external.h"
 | 
			
		||||
#include "hwc_mdpcomp.h"
 | 
			
		||||
#include "hwc_extonly.h"
 | 
			
		||||
#include "qcom_ui.h"
 | 
			
		||||
 | 
			
		||||
using namespace qhwc;
 | 
			
		||||
 | 
			
		||||
@@ -116,6 +117,8 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
 | 
			
		||||
        ctx->overlayInUse = false;
 | 
			
		||||
        ctx->mOverlay->setState(ovutils::OV_CLOSED);
 | 
			
		||||
        ctx->qbuf->unlockAll();
 | 
			
		||||
 | 
			
		||||
        qdutils::CBUtils::checkforGPULayer(list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -65,11 +65,10 @@ private:
 | 
			
		||||
    mutable range r;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int CopyBit::sYuvCount = 0;
 | 
			
		||||
int CopyBit::sYuvLayerIndex = -1;
 | 
			
		||||
bool CopyBit::sIsModeOn = false;
 | 
			
		||||
bool CopyBit::sIsLayerSkip = false;
 | 
			
		||||
bool CopyBit::sIsSkipLayerPresent = false;
 | 
			
		||||
bool CopyBit::sCopyBitDraw = false;
 | 
			
		||||
 | 
			
		||||
bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
 | 
			
		||||
    // return true for non-overlay targets
 | 
			
		||||
    if(ctx->mMDP.hasOverlay) {
 | 
			
		||||
@@ -82,14 +81,6 @@ bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx, hwc_layer_list_t *list) {
 | 
			
		||||
    int compositionType =
 | 
			
		||||
        qdutils::QCCompositionType::getInstance().getCompositionType();
 | 
			
		||||
 | 
			
		||||
    if (compositionType & qdutils::COMPOSITION_TYPE_C2D){
 | 
			
		||||
         if (sYuvCount) {
 | 
			
		||||
             //Overlay up & running. Dont use COPYBIT for RGB layers.
 | 
			
		||||
             // TODO need to implement blending with C2D
 | 
			
		||||
             return false;
 | 
			
		||||
         }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
 | 
			
		||||
        // DYN Composition:
 | 
			
		||||
        // use copybit, depending on dyn threshold
 | 
			
		||||
@@ -134,29 +125,34 @@ unsigned int CopyBit::getRGBRenderingArea(const hwc_layer_list_t *list) {
 | 
			
		||||
 | 
			
		||||
bool CopyBit::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) {
 | 
			
		||||
 | 
			
		||||
    sCopyBitDraw = false;
 | 
			
		||||
 | 
			
		||||
    int compositionType =
 | 
			
		||||
        qdutils::QCCompositionType::getInstance().getCompositionType();
 | 
			
		||||
 | 
			
		||||
    if ((compositionType & qdutils::COMPOSITION_TYPE_GPU) ||
 | 
			
		||||
        (compositionType & qdutils::COMPOSITION_TYPE_CPU))   {
 | 
			
		||||
    if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
 | 
			
		||||
        (compositionType == qdutils::COMPOSITION_TYPE_CPU))   {
 | 
			
		||||
        //GPU/CPU composition, don't change layer composition type
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool useCopybitForYUV = canUseCopybitForYUV(ctx);
 | 
			
		||||
    bool useCopybitForRGB = canUseCopybitForRGB(ctx, list);
 | 
			
		||||
 | 
			
		||||
    if(!(validateParams(ctx, list))) {
 | 
			
		||||
       ALOGE("%s:Invalid Params", __FUNCTION__);
 | 
			
		||||
       return false;
 | 
			
		||||
    }
 | 
			
		||||
    sCopyBitDraw = false;
 | 
			
		||||
 | 
			
		||||
    if(sIsSkipLayerPresent) {
 | 
			
		||||
        //GPU will be anyways used
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool useCopybitForYUV = canUseCopybitForYUV(ctx);
 | 
			
		||||
    bool useCopybitForRGB = canUseCopybitForRGB(ctx, list);
 | 
			
		||||
 | 
			
		||||
    for (int i=list->numHwLayers-1; i >= 0 ; i--) {
 | 
			
		||||
        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
 | 
			
		||||
 | 
			
		||||
        if (isSkipLayer(&list->hwLayers[i])) {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
 | 
			
		||||
        if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
 | 
			
		||||
          //YUV layer, check, if copybit can be used
 | 
			
		||||
          if (useCopybitForYUV) {
 | 
			
		||||
              list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ public:
 | 
			
		||||
    static bool draw(hwc_context_t *ctx, hwc_layer_list_t *list, EGLDisplay dpy,
 | 
			
		||||
                                                                EGLSurface sur);
 | 
			
		||||
    //Receives data from hwc
 | 
			
		||||
    static void setStats(int yuvCount, int yuvLayerIndex, bool isYuvLayerSkip);
 | 
			
		||||
    static void setStats(int skipCount);
 | 
			
		||||
 | 
			
		||||
    static void updateEglHandles(void*);
 | 
			
		||||
    static int  drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_t *layer,
 | 
			
		||||
@@ -55,15 +55,8 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    //Marks layer flags if this feature is used
 | 
			
		||||
    static void markFlags(hwc_layer_t *layer);
 | 
			
		||||
    //returns yuv count
 | 
			
		||||
    static int getYuvCount();
 | 
			
		||||
 | 
			
		||||
    //Number of yuv layers in this drawing round
 | 
			
		||||
    static int sYuvCount;
 | 
			
		||||
    //Index of YUV layer, relevant only if count is 1
 | 
			
		||||
    static int sYuvLayerIndex;
 | 
			
		||||
    //Flags if a yuv layer is animating or below something that is animating
 | 
			
		||||
    static bool sIsLayerSkip;
 | 
			
		||||
    //Flags on animation
 | 
			
		||||
    static bool sIsSkipLayerPresent;
 | 
			
		||||
    //Flags if this feature is on.
 | 
			
		||||
    static bool sIsModeOn;
 | 
			
		||||
    // flag that indicates whether CopyBit is enabled or not
 | 
			
		||||
@@ -88,17 +81,9 @@ private:
 | 
			
		||||
    static CopybitEngine* sInstance; // singleton
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline void CopyBit::setStats(int yuvCount, int yuvLayerIndex,
 | 
			
		||||
        bool isYuvLayerSkip) {
 | 
			
		||||
    sYuvCount = yuvCount;
 | 
			
		||||
    sYuvLayerIndex = yuvLayerIndex;
 | 
			
		||||
    sIsLayerSkip = isYuvLayerSkip;
 | 
			
		||||
inline void CopyBit::setStats(int skipCount) {
 | 
			
		||||
    sIsSkipLayerPresent = (skipCount != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int CopyBit::getYuvCount() { return sYuvCount; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}; //namespace qhwc
 | 
			
		||||
 | 
			
		||||
#endif //HWC_COPYBIT_H
 | 
			
		||||
 
 | 
			
		||||
@@ -166,14 +166,7 @@ void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
 | 
			
		||||
            //If BLOCK layer present, dont cache index, display BLOCK only.
 | 
			
		||||
            if(isExtBlockPresent == false) extLayerIndex = i;
 | 
			
		||||
        } else if (isSkipLayer(&list->hwLayers[i])) { //Popups
 | 
			
		||||
            //If video layer is below a skip layer
 | 
			
		||||
            if(yuvLayerIndex != -1 && yuvLayerIndex < (ssize_t)i) {
 | 
			
		||||
                //Do not mark as SKIP if it is secure buffer
 | 
			
		||||
                if (!yuvSecure) {
 | 
			
		||||
                    isYuvLayerSkip = true;
 | 
			
		||||
                    skipCount++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            skipCount++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -182,7 +175,7 @@ void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
 | 
			
		||||
    VideoPIP::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip,
 | 
			
		||||
            pipLayerIndex);
 | 
			
		||||
    ExtOnly::setStats(extCount, extLayerIndex, isExtBlockPresent);
 | 
			
		||||
    CopyBit::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);
 | 
			
		||||
    CopyBit::setStats(skipCount);
 | 
			
		||||
    MDPComp::setStats(skipCount);
 | 
			
		||||
 | 
			
		||||
    ctx->numHwLayers = list->numHwLayers;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,13 @@ include $(CLEAR_VARS)
 | 
			
		||||
 | 
			
		||||
LOCAL_MODULE                  := libqdutils
 | 
			
		||||
LOCAL_MODULE_TAGS             := optional
 | 
			
		||||
LOCAL_SHARED_LIBRARIES        := $(common_libs) libdl
 | 
			
		||||
LOCAL_C_INCLUDES              := $(common_includes)
 | 
			
		||||
LOCAL_SHARED_LIBRARIES        := $(common_libs) libdl libui libcutils
 | 
			
		||||
LOCAL_C_INCLUDES              += $(TOP)/hardware/qcom/display/libhwcomposer
 | 
			
		||||
LOCAL_C_INCLUDES              += $(TOP)/hardware/qcom/display/libgralloc
 | 
			
		||||
 | 
			
		||||
LOCAL_CFLAGS                  := $(common_flags)
 | 
			
		||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 | 
			
		||||
LOCAL_SRC_FILES               := profiler.cpp mdp_version.cpp \
 | 
			
		||||
                                 idle_invalidator.cpp egl_handles.cpp
 | 
			
		||||
                                 idle_invalidator.cpp egl_handles.cpp \
 | 
			
		||||
                                 cb_utils.cpp
 | 
			
		||||
include $(BUILD_SHARED_LIBRARY)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								libqdutils/clear_regions.h → libqdutils/cb_utils.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										67
									
								
								libqdutils/clear_regions.h → libqdutils/cb_utils.cpp
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -24,15 +24,52 @@
 | 
			
		||||
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 | 
			
		||||
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef QCOM_CLEARREGIONS_H
 | 
			
		||||
#define QCOM_CLEARREGIONS_H
 | 
			
		||||
 | 
			
		||||
#include <gralloc_priv.h>
 | 
			
		||||
#include <cutils/memory.h>
 | 
			
		||||
#include "stdio.h"
 | 
			
		||||
#include <comptype.h>
 | 
			
		||||
#include "egl_handles.h"
 | 
			
		||||
#include "hwc_utils.h"
 | 
			
		||||
#include "qcom_ui.h"
 | 
			
		||||
#include <cutils/memory.h>
 | 
			
		||||
 | 
			
		||||
namespace qdutils {
 | 
			
		||||
 | 
			
		||||
bool CBUtils::sGPUlayerpresent = 0;
 | 
			
		||||
 | 
			
		||||
void CBUtils::checkforGPULayer(const hwc_layer_list_t* list) {
 | 
			
		||||
    sGPUlayerpresent =  true;
 | 
			
		||||
    for(uint32_t index = 0; index < list->numHwLayers; index++) {
 | 
			
		||||
        const hwc_layer_t* layer = &list->hwLayers[index];
 | 
			
		||||
        if(layer->compositionType == HWC_FRAMEBUFFER) {
 | 
			
		||||
           sGPUlayerpresent =  true;
 | 
			
		||||
           break;
 | 
			
		||||
        }
 | 
			
		||||
        if(layer->flags & HWC_SKIP_LAYER) {
 | 
			
		||||
           sGPUlayerpresent =  true;
 | 
			
		||||
           break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if FB is updated by this composition type
 | 
			
		||||
 *
 | 
			
		||||
 * @param: composition type
 | 
			
		||||
 * @return: true if FB is updated, false if not
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
bool CBUtils::isUpdatingFB(int Type)
 | 
			
		||||
{
 | 
			
		||||
    switch((qhwc::HWCCompositionType)Type)
 | 
			
		||||
    {
 | 
			
		||||
        case qhwc::HWC_USE_COPYBIT:
 | 
			
		||||
            return true;
 | 
			
		||||
        default:
 | 
			
		||||
            ALOGE("%s: invalid composition type(%d)", __FUNCTION__, Type);
 | 
			
		||||
            return false;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clear Region implementation for C2D/MDP versions.
 | 
			
		||||
 *
 | 
			
		||||
@@ -42,23 +79,28 @@ namespace qdutils {
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success
 | 
			
		||||
 */
 | 
			
		||||
static int qcomuiClearRegion(Region region, EGLDisplay dpy){
 | 
			
		||||
 | 
			
		||||
int CBUtils::qcomuiClearRegion(Region region, EGLDisplay dpy){
 | 
			
		||||
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
    int compositionType = QCCompositionType::getInstance().getCompositionType();
 | 
			
		||||
    if (compositionType == COMPOSITION_TYPE_GPU){
 | 
			
		||||
         //SF can use the GPU to draw the wormhole.
 | 
			
		||||
    if ((compositionType == COMPOSITION_TYPE_GPU) || sGPUlayerpresent) {
 | 
			
		||||
        //return ERROR when GPU composition is used or any layer is flagged
 | 
			
		||||
        //for GPU composition.
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    android_native_buffer_t *renderBuffer =
 | 
			
		||||
          qdutils::eglHandles::getInstance().getAndroidNativeRenderBuffer(dpy);
 | 
			
		||||
 | 
			
		||||
    if (!renderBuffer) {
 | 
			
		||||
        ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
 | 
			
		||||
             __FUNCTION__);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
 | 
			
		||||
   private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
 | 
			
		||||
    if(!fbHandle) {
 | 
			
		||||
        ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
 | 
			
		||||
        return -1;
 | 
			
		||||
@@ -78,15 +120,16 @@ static int qcomuiClearRegion(Region region, EGLDisplay dpy){
 | 
			
		||||
            (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
 | 
			
		||||
        int w = r.width()*bytesPerPixel;
 | 
			
		||||
        int h = r.height();
 | 
			
		||||
 | 
			
		||||
        do {
 | 
			
		||||
            if(4 == bytesPerPixel)
 | 
			
		||||
            if(4 == bytesPerPixel){
 | 
			
		||||
                android_memset32((uint32_t*)dst, 0, w);
 | 
			
		||||
            else
 | 
			
		||||
            } else {
 | 
			
		||||
                android_memset16((uint16_t*)dst, 0, w);
 | 
			
		||||
            }
 | 
			
		||||
            dst += stride;
 | 
			
		||||
        } while(--h);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
}; //namespace qdutils
 | 
			
		||||
#endif /* end of include guard: QCOM_CLEARREGIONS_H*/
 | 
			
		||||
} //namespace
 | 
			
		||||
@@ -1,862 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 | 
			
		||||
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are
 | 
			
		||||
 * met:
 | 
			
		||||
 *   * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *     notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   * Redistributions in binary form must reproduce the above
 | 
			
		||||
 *     copyright notice, this list of conditions and the following
 | 
			
		||||
 *     disclaimer in the documentation and/or other materials provided
 | 
			
		||||
 *     with the distribution.
 | 
			
		||||
 *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
 | 
			
		||||
 *     contributors may be used to endorse or promote products derived
 | 
			
		||||
 *     from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 | 
			
		||||
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 | 
			
		||||
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | 
			
		||||
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 | 
			
		||||
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 | 
			
		||||
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <cutils/log.h>
 | 
			
		||||
#include <cutils/memory.h>
 | 
			
		||||
#include <qcom_ui.h>
 | 
			
		||||
#include <utils/comptype.h>
 | 
			
		||||
#include <gralloc_priv.h>
 | 
			
		||||
#include <alloc_controller.h>
 | 
			
		||||
#include <memalloc.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <EGL/eglext.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <SkBitmap.h>
 | 
			
		||||
#include <SkImageEncoder.h>
 | 
			
		||||
#include <Transform.h>
 | 
			
		||||
 | 
			
		||||
using gralloc::IMemAlloc;
 | 
			
		||||
using gralloc::IonController;
 | 
			
		||||
using gralloc::alloc_data;
 | 
			
		||||
using android::sp;
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
static android::sp<gralloc::IAllocController> sAlloc = 0;
 | 
			
		||||
 | 
			
		||||
int reallocate_memory(native_handle_t *buffer_handle, int mReqSize, int usage)
 | 
			
		||||
{
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
#ifndef NON_QCOM_TARGET
 | 
			
		||||
    if (sAlloc == 0) {
 | 
			
		||||
        sAlloc = gralloc::IAllocController::getInstance(true);
 | 
			
		||||
    }
 | 
			
		||||
    if (sAlloc == 0) {
 | 
			
		||||
        LOGE("sAlloc is still NULL");
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Dealloc the old memory
 | 
			
		||||
    private_handle_t *hnd = (private_handle_t *)buffer_handle;
 | 
			
		||||
    sp<IMemAlloc> memalloc = sAlloc->getAllocator(hnd->flags);
 | 
			
		||||
    ret = memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
 | 
			
		||||
 | 
			
		||||
    if (ret) {
 | 
			
		||||
        LOGE("%s: free_buffer failed", __FUNCTION__);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Realloc new memory
 | 
			
		||||
    alloc_data data;
 | 
			
		||||
    data.base = 0;
 | 
			
		||||
    data.fd = -1;
 | 
			
		||||
    data.offset = 0;
 | 
			
		||||
    data.size = mReqSize;
 | 
			
		||||
    data.align = getpagesize();
 | 
			
		||||
    data.uncached = true;
 | 
			
		||||
    int allocFlags = usage;
 | 
			
		||||
 | 
			
		||||
    switch (hnd->format) {
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
 | 
			
		||||
        case (HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED^HAL_PIXEL_FORMAT_INTERLACE): {
 | 
			
		||||
            data.align = 8192;
 | 
			
		||||
        } break;
 | 
			
		||||
        default: break;
 | 
			
		||||
    }
 | 
			
		||||
    ret = sAlloc->allocate(data, allocFlags, 0);
 | 
			
		||||
    if (ret == 0) {
 | 
			
		||||
        hnd->fd = data.fd;
 | 
			
		||||
        hnd->base = (int)data.base;
 | 
			
		||||
        hnd->offset = data.offset;
 | 
			
		||||
        hnd->size = data.size;
 | 
			
		||||
    } else {
 | 
			
		||||
        LOGE("%s: allocate failed", __FUNCTION__);
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
}; // ANONYNMOUS NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gets the number of arguments required for this operation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: operation whose argument count is required.
 | 
			
		||||
 *
 | 
			
		||||
 * @return -EINVAL if the operation is invalid.
 | 
			
		||||
 */
 | 
			
		||||
int getNumberOfArgsForOperation(int operation) {
 | 
			
		||||
    int num_args = -EINVAL;
 | 
			
		||||
    switch(operation) {
 | 
			
		||||
        case NATIVE_WINDOW_SET_BUFFERS_SIZE:
 | 
			
		||||
            num_args = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case  NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY:
 | 
			
		||||
            num_args = 3;
 | 
			
		||||
            break;
 | 
			
		||||
        case NATIVE_WINDOW_SET_PIXEL_ASPECT_RATIO:
 | 
			
		||||
            num_args = 2;
 | 
			
		||||
            break;
 | 
			
		||||
        default: LOGE("%s: invalid operation(0x%x)", __FUNCTION__, operation);
 | 
			
		||||
                 break;
 | 
			
		||||
    };
 | 
			
		||||
    return num_args;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if the format is supported by the GPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: format to check
 | 
			
		||||
 *
 | 
			
		||||
 * @return true if the format is supported by the GPU.
 | 
			
		||||
 */
 | 
			
		||||
bool isGPUSupportedFormat(int format) {
 | 
			
		||||
    if (format == HAL_PIXEL_FORMAT_YV12) {
 | 
			
		||||
        // We check the YV12 formats, since some Qcom specific formats
 | 
			
		||||
        // could have the bits set.
 | 
			
		||||
        return true;
 | 
			
		||||
    } else if ((format == HAL_PIXEL_FORMAT_RGB_888) ||
 | 
			
		||||
               (format == HAL_PIXEL_FORMAT_YCrCb_422_SP) ||
 | 
			
		||||
               (format == HAL_PIXEL_FORMAT_YCbCr_422_SP)){
 | 
			
		||||
        return false;
 | 
			
		||||
    } else if (format & INTERLACE_MASK) {
 | 
			
		||||
        // Interlaced content
 | 
			
		||||
        return false;
 | 
			
		||||
    } else if (format & S3D_FORMAT_MASK) {
 | 
			
		||||
        // S3D Formats are not supported by the GPU
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Function to check if the allocated buffer is of the correct size.
 | 
			
		||||
 * Reallocate the buffer with the correct size, if the size doesn't
 | 
			
		||||
 * match
 | 
			
		||||
 *
 | 
			
		||||
 * @param: handle of the allocated buffer
 | 
			
		||||
 * @param: requested size for the buffer
 | 
			
		||||
 * @param: usage flags
 | 
			
		||||
 *
 | 
			
		||||
 * return 0 on success
 | 
			
		||||
 */
 | 
			
		||||
int checkBuffer(native_handle_t *buffer_handle, int size, int usage)
 | 
			
		||||
{
 | 
			
		||||
    // If the client hasn't set a size, return
 | 
			
		||||
    if (0 >= size) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Validate the handle
 | 
			
		||||
    if (private_handle_t::validate(buffer_handle)) {
 | 
			
		||||
        LOGE("%s: handle is invalid", __FUNCTION__);
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Obtain the private_handle from the native handle
 | 
			
		||||
    private_handle_t *hnd = reinterpret_cast<private_handle_t*>(buffer_handle);
 | 
			
		||||
    if (hnd->size != size) {
 | 
			
		||||
        return reallocate_memory(hnd, size, usage);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if memory needs to be reallocated for this buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: Geometry of the current buffer.
 | 
			
		||||
 * @param: Required Geometry.
 | 
			
		||||
 * @param: Geometry of the updated buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @return True if a memory reallocation is required.
 | 
			
		||||
 */
 | 
			
		||||
bool needNewBuffer(const qBufGeometry currentGeometry,
 | 
			
		||||
                   const qBufGeometry requiredGeometry,
 | 
			
		||||
                   const qBufGeometry updatedGeometry)
 | 
			
		||||
{
 | 
			
		||||
    // If the current buffer info matches the updated info,
 | 
			
		||||
    // we do not require any memory allocation.
 | 
			
		||||
    if (updatedGeometry.width && updatedGeometry.height &&
 | 
			
		||||
        updatedGeometry.format) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (currentGeometry.width != requiredGeometry.width ||
 | 
			
		||||
        currentGeometry.height != requiredGeometry.height ||
 | 
			
		||||
        currentGeometry.format != requiredGeometry.format) {
 | 
			
		||||
        // Current and required geometry do not match. Allocation
 | 
			
		||||
        // required.
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Update the geometry of this buffer without reallocation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: buffer whose geometry needs to be updated.
 | 
			
		||||
 * @param: Updated width
 | 
			
		||||
 * @param: Updated height
 | 
			
		||||
 * @param: Updated format
 | 
			
		||||
 */
 | 
			
		||||
int updateBufferGeometry(sp<GraphicBuffer> buffer, const qBufGeometry updatedGeometry)
 | 
			
		||||
{
 | 
			
		||||
    if (buffer == 0) {
 | 
			
		||||
        LOGE("%s: graphic buffer is NULL", __FUNCTION__);
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!updatedGeometry.width || !updatedGeometry.height ||
 | 
			
		||||
        !updatedGeometry.format) {
 | 
			
		||||
        // No update required. Return.
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (buffer->width == updatedGeometry.width &&
 | 
			
		||||
        buffer->height == updatedGeometry.height &&
 | 
			
		||||
        buffer->format == updatedGeometry.format) {
 | 
			
		||||
        // The buffer has already been updated. Return.
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Validate the handle
 | 
			
		||||
    if (private_handle_t::validate(buffer->handle)) {
 | 
			
		||||
        LOGE("%s: handle is invalid", __FUNCTION__);
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
    buffer->width  = updatedGeometry.width;
 | 
			
		||||
    buffer->height = updatedGeometry.height;
 | 
			
		||||
    buffer->format = updatedGeometry.format;
 | 
			
		||||
    private_handle_t *hnd = (private_handle_t*)(buffer->handle);
 | 
			
		||||
    if (hnd) {
 | 
			
		||||
        hnd->width  = updatedGeometry.width;
 | 
			
		||||
        hnd->height = updatedGeometry.height;
 | 
			
		||||
        hnd->format = updatedGeometry.format;
 | 
			
		||||
    } else {
 | 
			
		||||
        LOGE("%s: hnd is NULL", __FUNCTION__);
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Update the S3D format of this buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: buffer whosei S3D format needs to be updated.
 | 
			
		||||
 * @param: Updated buffer S3D format
 | 
			
		||||
 */
 | 
			
		||||
int updateBufferS3DFormat(sp<GraphicBuffer> buffer, const int s3dFormat)
 | 
			
		||||
{
 | 
			
		||||
    if (buffer == 0) {
 | 
			
		||||
        LOGE("%s: graphic buffer is NULL", __FUNCTION__);
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buffer->format |= s3dFormat;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
 * Updates the flags for the layer
 | 
			
		||||
 *
 | 
			
		||||
 * @param: Attribute
 | 
			
		||||
 * @param: Identifies if the attribute was enabled or disabled.
 | 
			
		||||
 *
 | 
			
		||||
 * @return: -EINVAL if the attribute is invalid
 | 
			
		||||
 */
 | 
			
		||||
int updateLayerQcomFlags(eLayerAttrib attribute, bool enable, int& currentFlags)
 | 
			
		||||
{
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
    switch (attribute) {
 | 
			
		||||
        case LAYER_UPDATE_STATUS: {
 | 
			
		||||
            if (enable)
 | 
			
		||||
                currentFlags |= LAYER_UPDATING;
 | 
			
		||||
            else
 | 
			
		||||
                currentFlags &= ~LAYER_UPDATING;
 | 
			
		||||
        } break;
 | 
			
		||||
        case LAYER_ASYNCHRONOUS_STATUS: {
 | 
			
		||||
            if (enable)
 | 
			
		||||
                currentFlags |= LAYER_ASYNCHRONOUS;
 | 
			
		||||
            else
 | 
			
		||||
                currentFlags &= ~LAYER_ASYNCHRONOUS;
 | 
			
		||||
        } break;
 | 
			
		||||
        default: LOGE("%s: invalid attribute(0x%x)", __FUNCTION__, attribute);
 | 
			
		||||
                 break;
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gets the per frame HWC flags for this layer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: current hwcl flags
 | 
			
		||||
 * @param: current layerFlags
 | 
			
		||||
 *
 | 
			
		||||
 * @return: the per frame flags.
 | 
			
		||||
 */
 | 
			
		||||
int getPerFrameFlags(int hwclFlags, int layerFlags) {
 | 
			
		||||
    int flags = hwclFlags;
 | 
			
		||||
    if (layerFlags & LAYER_UPDATING)
 | 
			
		||||
        flags &= ~HWC_LAYER_NOT_UPDATING;
 | 
			
		||||
    else
 | 
			
		||||
        flags |= HWC_LAYER_NOT_UPDATING;
 | 
			
		||||
 | 
			
		||||
    if (layerFlags & LAYER_ASYNCHRONOUS)
 | 
			
		||||
        flags |= HWC_LAYER_ASYNCHRONOUS;
 | 
			
		||||
    else
 | 
			
		||||
        flags &= ~HWC_LAYER_ASYNCHRONOUS;
 | 
			
		||||
 | 
			
		||||
    return flags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if FB is updated by this composition type
 | 
			
		||||
 *
 | 
			
		||||
 * @param: composition type
 | 
			
		||||
 * @return: true if FB is updated, false if not
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
bool isUpdatingFB(HWCCompositionType compositionType)
 | 
			
		||||
{
 | 
			
		||||
    switch(compositionType)
 | 
			
		||||
    {
 | 
			
		||||
        case HWC_USE_COPYBIT:
 | 
			
		||||
            return true;
 | 
			
		||||
        default:
 | 
			
		||||
            LOGE("%s: invalid composition type(%d)", __FUNCTION__, compositionType);
 | 
			
		||||
            return false;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clear Region implementation for C2D/MDP versions.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: region to be cleared
 | 
			
		||||
 * @param: EGL Display
 | 
			
		||||
 * @param: EGL Surface
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success
 | 
			
		||||
 */
 | 
			
		||||
int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur)
 | 
			
		||||
{
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
    int compositionType = QCCompositionType::getInstance().getCompositionType();
 | 
			
		||||
 | 
			
		||||
    if (compositionType & COMPOSITION_TYPE_GPU ||
 | 
			
		||||
        (compositionType == COMPOSITION_TYPE_DYN|COMPOSITION_TYPE_C2D))
 | 
			
		||||
    {
 | 
			
		||||
        // For GPU or DYN comp. with C2D, return an error, so that SF can use
 | 
			
		||||
        // the GPU to draw the wormhole.
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    android_native_buffer_t *renderBuffer = (android_native_buffer_t *)
 | 
			
		||||
        eglGetRenderBufferANDROID(dpy, sur);
 | 
			
		||||
    if (!renderBuffer) {
 | 
			
		||||
        LOGE("%s: eglGetRenderBufferANDROID returned NULL buffer",
 | 
			
		||||
             __FUNCTION__);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle;
 | 
			
		||||
    if(!fbHandle) {
 | 
			
		||||
        LOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int bytesPerPixel = 4;
 | 
			
		||||
    if (HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format) {
 | 
			
		||||
        bytesPerPixel = 2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Region::const_iterator it = region.begin();
 | 
			
		||||
    Region::const_iterator const end = region.end();
 | 
			
		||||
    const int32_t stride = renderBuffer->stride*bytesPerPixel;
 | 
			
		||||
    while (it != end) {
 | 
			
		||||
        const Rect& r = *it++;
 | 
			
		||||
        uint8_t* dst = (uint8_t*) fbHandle->base +
 | 
			
		||||
            (r.left + r.top*renderBuffer->stride)*bytesPerPixel;
 | 
			
		||||
        int w = r.width()*bytesPerPixel;
 | 
			
		||||
        int h = r.height();
 | 
			
		||||
        do {
 | 
			
		||||
            if(4 == bytesPerPixel)
 | 
			
		||||
                android_memset32((uint32_t*)dst, 0, w);
 | 
			
		||||
            else
 | 
			
		||||
                android_memset16((uint16_t*)dst, 0, w);
 | 
			
		||||
            dst += stride;
 | 
			
		||||
        } while(--h);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Handles the externalDisplay event
 | 
			
		||||
 * HDMI has highest priority compared to WifiDisplay
 | 
			
		||||
 * Based on the current and the new display type, decides the
 | 
			
		||||
 * external display to be enabled
 | 
			
		||||
 *
 | 
			
		||||
 * @param: disp - external display type(wfd/hdmi)
 | 
			
		||||
 * @param: value - external event(0/1)
 | 
			
		||||
 * @param: currdispType - Current enabled external display Type
 | 
			
		||||
 * @return: external display type to be enabled
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
external_display_type handleEventHDMI(external_display_type disp, int value,
 | 
			
		||||
                                      external_display_type currDispType)
 | 
			
		||||
{
 | 
			
		||||
    external_display_type retDispType = currDispType;
 | 
			
		||||
    switch(disp) {
 | 
			
		||||
        case EXT_TYPE_HDMI:
 | 
			
		||||
            if(value)
 | 
			
		||||
                retDispType = EXT_TYPE_HDMI;
 | 
			
		||||
            else
 | 
			
		||||
                retDispType = EXT_TYPE_NONE;
 | 
			
		||||
            break;
 | 
			
		||||
        case EXT_TYPE_WIFI:
 | 
			
		||||
            if(currDispType != EXT_TYPE_HDMI) {
 | 
			
		||||
                if(value)
 | 
			
		||||
                    retDispType = EXT_TYPE_WIFI;
 | 
			
		||||
                else
 | 
			
		||||
                    retDispType = EXT_TYPE_NONE;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            LOGE("%s: Unknown External Display Type!!");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    return retDispType;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Using global variables for layer dumping since "property_set("debug.sf.dump",
 | 
			
		||||
// property)" does not work.
 | 
			
		||||
int sfdump_countlimit_raw = 0;
 | 
			
		||||
int sfdump_counter_raw = 1;
 | 
			
		||||
char sfdump_propstr_persist_raw[PROPERTY_VALUE_MAX] = "";
 | 
			
		||||
char sfdumpdir_raw[256] = "";
 | 
			
		||||
int sfdump_countlimit_png = 0;
 | 
			
		||||
int sfdump_counter_png = 1;
 | 
			
		||||
char sfdump_propstr_persist_png[PROPERTY_VALUE_MAX] = "";
 | 
			
		||||
char sfdumpdir_png[256] = "";
 | 
			
		||||
 | 
			
		||||
bool needToDumpLayers()
 | 
			
		||||
{
 | 
			
		||||
    bool bDumpLayer = false;
 | 
			
		||||
    char sfdump_propstr[PROPERTY_VALUE_MAX];
 | 
			
		||||
    time_t timenow;
 | 
			
		||||
    tm sfdump_time;
 | 
			
		||||
 | 
			
		||||
    time(&timenow);
 | 
			
		||||
    localtime_r(&timenow, &sfdump_time);
 | 
			
		||||
 | 
			
		||||
    if ((property_get("debug.sf.dump.png", sfdump_propstr, NULL) > 0) &&
 | 
			
		||||
        (strncmp(sfdump_propstr, sfdump_propstr_persist_png,
 | 
			
		||||
                 PROPERTY_VALUE_MAX - 1))) {
 | 
			
		||||
        // Strings exist & not equal implies it has changed, so trigger a dump
 | 
			
		||||
        strncpy(sfdump_propstr_persist_png, sfdump_propstr,
 | 
			
		||||
                PROPERTY_VALUE_MAX - 1);
 | 
			
		||||
        sfdump_countlimit_png = atoi(sfdump_propstr);
 | 
			
		||||
        sfdump_countlimit_png = (sfdump_countlimit_png < 0) ? 0:
 | 
			
		||||
            (sfdump_countlimit_png >= LONG_MAX) ? (LONG_MAX - 1):
 | 
			
		||||
            sfdump_countlimit_png;
 | 
			
		||||
        if (sfdump_countlimit_png) {
 | 
			
		||||
            sprintf(sfdumpdir_png,"/data/sfdump.png%04d%02d%02d.%02d%02d%02d",
 | 
			
		||||
                    sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
 | 
			
		||||
                    sfdump_time.tm_mday, sfdump_time.tm_hour,
 | 
			
		||||
                    sfdump_time.tm_min, sfdump_time.tm_sec);
 | 
			
		||||
            if (0 == mkdir(sfdumpdir_png, 0777))
 | 
			
		||||
                sfdump_counter_png = 0;
 | 
			
		||||
            else
 | 
			
		||||
                LOGE("sfdump: Error: %s. Failed to create sfdump directory"
 | 
			
		||||
                     ": %s", strerror(errno), sfdumpdir_png);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (sfdump_counter_png <= sfdump_countlimit_png)
 | 
			
		||||
        sfdump_counter_png++;
 | 
			
		||||
 | 
			
		||||
    if ((property_get("debug.sf.dump", sfdump_propstr, NULL) > 0) &&
 | 
			
		||||
        (strncmp(sfdump_propstr, sfdump_propstr_persist_raw,
 | 
			
		||||
                 PROPERTY_VALUE_MAX - 1))) {
 | 
			
		||||
        // Strings exist & not equal implies it has changed, so trigger a dump
 | 
			
		||||
        strncpy(sfdump_propstr_persist_raw, sfdump_propstr,
 | 
			
		||||
                PROPERTY_VALUE_MAX - 1);
 | 
			
		||||
        sfdump_countlimit_raw = atoi(sfdump_propstr);
 | 
			
		||||
        sfdump_countlimit_raw = (sfdump_countlimit_raw < 0) ? 0:
 | 
			
		||||
            (sfdump_countlimit_raw >= LONG_MAX) ? (LONG_MAX - 1):
 | 
			
		||||
            sfdump_countlimit_raw;
 | 
			
		||||
        if (sfdump_countlimit_raw) {
 | 
			
		||||
            sprintf(sfdumpdir_raw,"/data/sfdump.raw%04d%02d%02d.%02d%02d%02d",
 | 
			
		||||
                    sfdump_time.tm_year + 1900, sfdump_time.tm_mon + 1,
 | 
			
		||||
                    sfdump_time.tm_mday, sfdump_time.tm_hour,
 | 
			
		||||
                    sfdump_time.tm_min, sfdump_time.tm_sec);
 | 
			
		||||
            if (0 == mkdir(sfdumpdir_raw, 0777))
 | 
			
		||||
                sfdump_counter_raw = 0;
 | 
			
		||||
            else
 | 
			
		||||
                LOGE("sfdump: Error: %s. Failed to create sfdump directory"
 | 
			
		||||
                     ": %s", strerror(errno), sfdumpdir_raw);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (sfdump_counter_raw <= sfdump_countlimit_raw)
 | 
			
		||||
        sfdump_counter_raw++;
 | 
			
		||||
 | 
			
		||||
    bDumpLayer = (sfdump_countlimit_png || sfdump_countlimit_raw)? true : false;
 | 
			
		||||
    return bDumpLayer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void getHalPixelFormatStr(int format, char pixelformatstr[])
 | 
			
		||||
{
 | 
			
		||||
    if (!pixelformatstr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    switch(format) {
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RGBA_8888:
 | 
			
		||||
            strcpy(pixelformatstr, "RGBA_8888");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RGBX_8888:
 | 
			
		||||
            strcpy(pixelformatstr, "RGBX_8888");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RGB_888:
 | 
			
		||||
            strcpy(pixelformatstr, "RGB_888");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RGB_565:
 | 
			
		||||
            strcpy(pixelformatstr, "RGB_565");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_BGRA_8888:
 | 
			
		||||
            strcpy(pixelformatstr, "BGRA_8888");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RGBA_5551:
 | 
			
		||||
            strcpy(pixelformatstr, "RGBA_5551");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RGBA_4444:
 | 
			
		||||
            strcpy(pixelformatstr, "RGBA_4444");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YV12:
 | 
			
		||||
            strcpy(pixelformatstr, "YV12");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
 | 
			
		||||
            strcpy(pixelformatstr, "YCbCr_422_SP_NV16");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
 | 
			
		||||
            strcpy(pixelformatstr, "YCrCb_420_SP_NV21");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCbCr_422_I:
 | 
			
		||||
            strcpy(pixelformatstr, "YCbCr_422_I_YUY2");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
 | 
			
		||||
            strcpy(pixelformatstr, "NV12_ENCODEABLE");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
 | 
			
		||||
            strcpy(pixelformatstr, "YCbCr_420_SP_TILED_TILE_4x2");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
 | 
			
		||||
            strcpy(pixelformatstr, "YCbCr_420_SP");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
 | 
			
		||||
            strcpy(pixelformatstr, "YCrCb_420_SP_ADRENO");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
 | 
			
		||||
            strcpy(pixelformatstr, "YCrCb_422_SP");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_R_8:
 | 
			
		||||
            strcpy(pixelformatstr, "R_8");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_RG_88:
 | 
			
		||||
            strcpy(pixelformatstr, "RG_88");
 | 
			
		||||
            break;
 | 
			
		||||
        case HAL_PIXEL_FORMAT_INTERLACE:
 | 
			
		||||
            strcpy(pixelformatstr, "INTERLACE");
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            sprintf(pixelformatstr, "Unknown0x%X", format);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
 | 
			
		||||
               hwc_layer_t hwLayers[])
 | 
			
		||||
{
 | 
			
		||||
    char dumplogstr_png[128] = "";
 | 
			
		||||
    char dumplogstr_raw[128] = "";
 | 
			
		||||
    if (sfdump_counter_png <= sfdump_countlimit_png) {
 | 
			
		||||
        sprintf(dumplogstr_png, "[png-dump-frame: %03d of %03d] ",
 | 
			
		||||
                sfdump_counter_png, sfdump_countlimit_png);
 | 
			
		||||
    }
 | 
			
		||||
    if (sfdump_counter_raw <= sfdump_countlimit_raw) {
 | 
			
		||||
        sprintf(dumplogstr_raw, "[raw-dump-frame: %03d of %03d]",
 | 
			
		||||
                sfdump_counter_raw, sfdump_countlimit_raw);
 | 
			
		||||
    }
 | 
			
		||||
    if (NULL == hwLayers) {
 | 
			
		||||
        LOGE("sfdump: Error.%s%sLayer[%d] No hwLayers to dump.",
 | 
			
		||||
             dumplogstr_raw, dumplogstr_png, layerIndex);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    hwc_layer *layer = &hwLayers[layerIndex];
 | 
			
		||||
    hwc_rect_t sourceCrop = layer->sourceCrop;
 | 
			
		||||
    hwc_rect_t displayFrame = layer->displayFrame;
 | 
			
		||||
    private_handle_t *hnd = (private_handle_t *)layer->handle;
 | 
			
		||||
    char pixelformatstr[32] = "None";
 | 
			
		||||
 | 
			
		||||
    if (hnd)
 | 
			
		||||
        getHalPixelFormatStr(hnd->format, pixelformatstr);
 | 
			
		||||
 | 
			
		||||
    LOGE("sfdump: %s%s[%s]-Composition, Layer[%d] SrcBuff[%dx%d] "
 | 
			
		||||
         "SrcCrop[%dl, %dt, %dr, %db] "
 | 
			
		||||
         "DispFrame[%dl, %dt, %dr, %db] Composition-type = %s, Format = %s, "
 | 
			
		||||
         "Orientation = %s, Flags = %s%s%s%s%s%s%s%s%s%s",
 | 
			
		||||
         dumplogstr_raw, dumplogstr_png,
 | 
			
		||||
         (moduleCompositionType == COMPOSITION_TYPE_GPU)? "GPU":
 | 
			
		||||
         (moduleCompositionType == COMPOSITION_TYPE_MDP)? "MDP":
 | 
			
		||||
         (moduleCompositionType == COMPOSITION_TYPE_C2D)? "C2D":
 | 
			
		||||
         (moduleCompositionType == COMPOSITION_TYPE_CPU)? "CPU":
 | 
			
		||||
         (moduleCompositionType == COMPOSITION_TYPE_DYN)? "DYN": "???",
 | 
			
		||||
         layerIndex,
 | 
			
		||||
         (hnd)? hnd->width : -1, (hnd)? hnd->height : -1,
 | 
			
		||||
         sourceCrop.left, sourceCrop.top,
 | 
			
		||||
         sourceCrop.right, sourceCrop.bottom,
 | 
			
		||||
         displayFrame.left, displayFrame.top,
 | 
			
		||||
         displayFrame.right, displayFrame.bottom,
 | 
			
		||||
         (layer->compositionType == HWC_FRAMEBUFFER)? "Framebuffer (OpenGL ES)":
 | 
			
		||||
         (layer->compositionType == HWC_OVERLAY)? "Overlay":
 | 
			
		||||
         (layer->compositionType == HWC_USE_COPYBIT)? "Copybit": "???",
 | 
			
		||||
         pixelformatstr,
 | 
			
		||||
         (layer->transform == Transform::ROT_0)? "ROT_0":
 | 
			
		||||
             (layer->transform == Transform::FLIP_H)? "FLIP_H":
 | 
			
		||||
             (layer->transform == Transform::FLIP_V)? "FLIP_V":
 | 
			
		||||
             (layer->transform == Transform::ROT_90)? "ROT_90":
 | 
			
		||||
             (layer->transform == Transform::ROT_180)? "ROT_180":
 | 
			
		||||
             (layer->transform == Transform::ROT_270)? "ROT_270":
 | 
			
		||||
             (layer->transform == Transform::ROT_INVALID)? "ROT_INVALID":"???",
 | 
			
		||||
         (layer->flags == 0)? "[None]":"",
 | 
			
		||||
         (layer->flags & HWC_SKIP_LAYER)? "[Skip layer]":"",
 | 
			
		||||
         (layer->flags & HWC_LAYER_NOT_UPDATING)? "[Layer not updating]":"",
 | 
			
		||||
         (layer->flags & HWC_COMP_BYPASS)? "[Bypass]":"",
 | 
			
		||||
         (layer->flags & HWC_BYPASS_RESERVE_0)? "[Bypass Reserve 0]":"",
 | 
			
		||||
         (layer->flags & HWC_BYPASS_RESERVE_1)? "[Bypass Reserve 1]":"",
 | 
			
		||||
         (listFlags & HWC_GEOMETRY_CHANGED)? "[List: Geometry Changed]":"",
 | 
			
		||||
         (listFlags & HWC_SKIP_COMPOSITION)? "[List: Skip Composition]":"");
 | 
			
		||||
 | 
			
		||||
    if (NULL == hnd) {
 | 
			
		||||
        LOGE("sfdump: %s%sLayer[%d] private-handle is invalid.",
 | 
			
		||||
             dumplogstr_raw, dumplogstr_png, layerIndex);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((sfdump_counter_png <= sfdump_countlimit_png) && hnd->base) {
 | 
			
		||||
        bool bResult = false;
 | 
			
		||||
        char sfdumpfile_name[256];
 | 
			
		||||
        SkBitmap *tempSkBmp = new SkBitmap();
 | 
			
		||||
        SkBitmap::Config tempSkBmpConfig = SkBitmap::kNo_Config;
 | 
			
		||||
        sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d.png", sfdumpdir_png,
 | 
			
		||||
                sfdump_counter_png, layerIndex);
 | 
			
		||||
 | 
			
		||||
        switch (hnd->format) {
 | 
			
		||||
            case HAL_PIXEL_FORMAT_RGBA_8888:
 | 
			
		||||
            case HAL_PIXEL_FORMAT_RGBX_8888:
 | 
			
		||||
            case HAL_PIXEL_FORMAT_BGRA_8888:
 | 
			
		||||
                tempSkBmpConfig = SkBitmap::kARGB_8888_Config;
 | 
			
		||||
                break;
 | 
			
		||||
            case HAL_PIXEL_FORMAT_RGB_565:
 | 
			
		||||
            case HAL_PIXEL_FORMAT_RGBA_5551:
 | 
			
		||||
            case HAL_PIXEL_FORMAT_RGBA_4444:
 | 
			
		||||
                tempSkBmpConfig = SkBitmap::kRGB_565_Config;
 | 
			
		||||
                break;
 | 
			
		||||
            case HAL_PIXEL_FORMAT_RGB_888:
 | 
			
		||||
            default:
 | 
			
		||||
                tempSkBmpConfig = SkBitmap::kNo_Config;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        if (SkBitmap::kNo_Config != tempSkBmpConfig) {
 | 
			
		||||
            tempSkBmp->setConfig(tempSkBmpConfig, hnd->width, hnd->height);
 | 
			
		||||
            tempSkBmp->setPixels((void*)hnd->base);
 | 
			
		||||
            bResult = SkImageEncoder::EncodeFile(sfdumpfile_name,
 | 
			
		||||
                                                 *tempSkBmp, SkImageEncoder::kPNG_Type, 100);
 | 
			
		||||
            LOGE("sfdump: %sDumped Layer[%d] to %s: %s", dumplogstr_png,
 | 
			
		||||
                 layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            LOGE("sfdump: %sSkipping Layer[%d] dump: Unsupported layer "
 | 
			
		||||
                 "format %s for png encoder.", dumplogstr_png, layerIndex,
 | 
			
		||||
                 pixelformatstr);
 | 
			
		||||
        }
 | 
			
		||||
        delete tempSkBmp; // Calls SkBitmap::freePixels() internally.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((sfdump_counter_raw <= sfdump_countlimit_raw) && hnd->base) {
 | 
			
		||||
        char sfdumpfile_name[256];
 | 
			
		||||
        bool bResult = false;
 | 
			
		||||
        sprintf(sfdumpfile_name, "%s/sfdump%03d_layer%d_%dx%d_%s.raw",
 | 
			
		||||
                sfdumpdir_raw,
 | 
			
		||||
                sfdump_counter_raw, layerIndex, hnd->width, hnd->height,
 | 
			
		||||
                pixelformatstr);
 | 
			
		||||
        FILE* fp = fopen(sfdumpfile_name, "w+");
 | 
			
		||||
        if (fp != NULL) {
 | 
			
		||||
            bResult = (bool) fwrite((void*)hnd->base, hnd->size, 1, fp);
 | 
			
		||||
            fclose(fp);
 | 
			
		||||
        }
 | 
			
		||||
        LOGE("sfdump: %s Dumped Layer[%d] to %s: %s", dumplogstr_raw,
 | 
			
		||||
             layerIndex, sfdumpfile_name, bResult ? "Success" : "Fail");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool needsAspectRatio (int wRatio, int hRatio) {
 | 
			
		||||
    return ((wRatio != DEFAULT_WIDTH_RATIO) || (hRatio != DEFAULT_HEIGHT_RATIO));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void applyPixelAspectRatio (int wRatio, int hRatio, int orientation, int maxWidth,
 | 
			
		||||
                            int maxHeight, Rect& visibleRect, GLfloat mVertices[][2]) {
 | 
			
		||||
 | 
			
		||||
    if ((wRatio == 0) || (hRatio == 0))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    float wDelta = 0;
 | 
			
		||||
    float hDelta = 0;
 | 
			
		||||
    float aspectRatio;
 | 
			
		||||
    float displayRatio;
 | 
			
		||||
    float new_width, new_height;
 | 
			
		||||
    float old_width = abs(visibleRect.right - visibleRect.left);
 | 
			
		||||
    float old_height = abs(visibleRect.bottom - visibleRect.top);
 | 
			
		||||
 | 
			
		||||
    if (orientation == Transform::ROT_INVALID) {
 | 
			
		||||
        // During animation, no defined orientation, rely on mTransformedBounds
 | 
			
		||||
        if (old_width >= old_height)
 | 
			
		||||
            orientation = Transform::ROT_0;
 | 
			
		||||
        else
 | 
			
		||||
            orientation = Transform::ROT_90;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (orientation) {
 | 
			
		||||
 | 
			
		||||
        case Transform::ROT_0:
 | 
			
		||||
        case Transform::ROT_180:
 | 
			
		||||
 | 
			
		||||
            // Calculated Aspect Ratio = Original Aspect Ratio x Pixel Aspect Ratio
 | 
			
		||||
            aspectRatio = (old_width * wRatio) / (old_height * hRatio);
 | 
			
		||||
            displayRatio = (float)maxWidth / (float)maxHeight;
 | 
			
		||||
 | 
			
		||||
            if (aspectRatio >= displayRatio) {
 | 
			
		||||
                new_height = old_width / aspectRatio;
 | 
			
		||||
                if (new_height > maxHeight) {
 | 
			
		||||
                    new_height = maxHeight;
 | 
			
		||||
                    new_width = new_height * aspectRatio;
 | 
			
		||||
                    wDelta = (new_width - old_width) / 2;
 | 
			
		||||
                }
 | 
			
		||||
                hDelta = (new_height - old_height) / 2;
 | 
			
		||||
            } else {
 | 
			
		||||
                new_width = old_height * aspectRatio;
 | 
			
		||||
                if (new_width > maxWidth) {
 | 
			
		||||
                    new_width = maxWidth;
 | 
			
		||||
                    new_height = new_width / aspectRatio;
 | 
			
		||||
                    hDelta = (new_height - old_height) / 2;
 | 
			
		||||
                }
 | 
			
		||||
                wDelta = (new_width - old_width) / 2;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (hDelta != 0) {
 | 
			
		||||
                visibleRect.top -= hDelta;
 | 
			
		||||
                visibleRect.bottom += hDelta;
 | 
			
		||||
 | 
			
		||||
                // Set mVertices for GPU fallback (During rotation)
 | 
			
		||||
                if (orientation == Transform::ROT_0) {
 | 
			
		||||
                    mVertices[1][1] = mVertices[2][1] = visibleRect.top;
 | 
			
		||||
                    mVertices[0][1] = mVertices[3][1] = visibleRect.bottom;
 | 
			
		||||
                } else {
 | 
			
		||||
                    mVertices[0][1] = mVertices[3][1] = visibleRect.top;
 | 
			
		||||
                    mVertices[1][1] = mVertices[2][1] = visibleRect.bottom;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (wDelta != 0) {
 | 
			
		||||
                visibleRect.left -= wDelta;
 | 
			
		||||
                visibleRect.right += wDelta;
 | 
			
		||||
 | 
			
		||||
                // Set mVertices for GPU fallback (During rotation)
 | 
			
		||||
                mVertices[0][0] = mVertices[1][0] = visibleRect.left;
 | 
			
		||||
                mVertices[2][0] = mVertices[3][0] = visibleRect.right;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case Transform::ROT_90:
 | 
			
		||||
        case Transform::ROT_270:
 | 
			
		||||
 | 
			
		||||
            // Calculated Aspect Ratio = Original Aspect Ratio x Pixel Aspect Ratio
 | 
			
		||||
            aspectRatio = (old_height * wRatio) / (old_width * hRatio);
 | 
			
		||||
            displayRatio = (float)maxHeight / (float)maxWidth;
 | 
			
		||||
 | 
			
		||||
            if (aspectRatio >= displayRatio) {
 | 
			
		||||
                new_height = old_width * aspectRatio;
 | 
			
		||||
                if (new_height > maxHeight) {
 | 
			
		||||
                    new_height = maxHeight;
 | 
			
		||||
                    new_width = new_height / aspectRatio;
 | 
			
		||||
                    wDelta = (new_width - old_width) / 2;
 | 
			
		||||
                }
 | 
			
		||||
                hDelta = (new_height - old_height) / 2;
 | 
			
		||||
            } else {
 | 
			
		||||
                new_width = old_height / aspectRatio;
 | 
			
		||||
                if (new_width > maxWidth) {
 | 
			
		||||
                    new_width = maxWidth;
 | 
			
		||||
                    new_height = new_width * aspectRatio;
 | 
			
		||||
                    hDelta = (new_height - old_height) / 2;
 | 
			
		||||
                }
 | 
			
		||||
                wDelta = (new_width - old_width) / 2;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (hDelta != 0) {
 | 
			
		||||
                visibleRect.top -= hDelta;
 | 
			
		||||
                visibleRect.bottom += hDelta;
 | 
			
		||||
 | 
			
		||||
                // Set mVertices for GPU fallback (During rotation)
 | 
			
		||||
                if (orientation == Transform::ROT_90) {
 | 
			
		||||
                    mVertices[2][1] = mVertices[3][1] = visibleRect.top;
 | 
			
		||||
                    mVertices[0][1] = mVertices[1][1] = visibleRect.bottom;
 | 
			
		||||
                } else {
 | 
			
		||||
                    mVertices[0][1] = mVertices[1][1] = visibleRect.top;
 | 
			
		||||
                    mVertices[2][1] = mVertices[3][1] = visibleRect.bottom;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (wDelta != 0) {
 | 
			
		||||
                visibleRect.left -= wDelta;
 | 
			
		||||
                visibleRect.right += wDelta;
 | 
			
		||||
 | 
			
		||||
                // Set mVertices for GPU fallback (During rotation)
 | 
			
		||||
                if (orientation == Transform::ROT_90) {
 | 
			
		||||
                    mVertices[1][0] = mVertices[2][0] = visibleRect.left;
 | 
			
		||||
                    mVertices[0][0] = mVertices[3][0] = visibleRect.right;
 | 
			
		||||
                } else {
 | 
			
		||||
                    mVertices[0][0] = mVertices[3][0] = visibleRect.left;
 | 
			
		||||
                    mVertices[1][0] = mVertices[2][0] = visibleRect.right;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default: // Handled above.
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										303
									
								
								libqdutils/qcom_ui.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										303
									
								
								libqdutils/qcom_ui.h
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,6 +1,4 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 | 
			
		||||
 | 
			
		||||
/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are
 | 
			
		||||
 * met:
 | 
			
		||||
@@ -26,292 +24,25 @@
 | 
			
		||||
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 | 
			
		||||
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef QCOM_UTIL_H
 | 
			
		||||
#define QCOM_UTIL_H
 | 
			
		||||
 | 
			
		||||
#ifndef INCLUDE_LIBQCOM_UI
 | 
			
		||||
#define INCLUDE_LIBQCOM_UI
 | 
			
		||||
 | 
			
		||||
#include <cutils/native_handle.h>
 | 
			
		||||
#include <ui/GraphicBuffer.h>
 | 
			
		||||
#include <hardware/hwcomposer.h>
 | 
			
		||||
#include <gralloc_priv.h>
 | 
			
		||||
#include <comptype.h>
 | 
			
		||||
#include <ui/Region.h>
 | 
			
		||||
#include <EGL/egl.h>
 | 
			
		||||
#include <GLES/gl.h>
 | 
			
		||||
#include <utils/Singleton.h>
 | 
			
		||||
#include <cutils/properties.h>
 | 
			
		||||
#include <hardware/hwcomposer.h>
 | 
			
		||||
#include "egl_handles.h"
 | 
			
		||||
 | 
			
		||||
using namespace android;
 | 
			
		||||
using android::sp;
 | 
			
		||||
using android::GraphicBuffer;
 | 
			
		||||
namespace qdutils {
 | 
			
		||||
class CBUtils {
 | 
			
		||||
 | 
			
		||||
#define HWC_BYPASS_INDEX_MASK 0x00000030
 | 
			
		||||
#define DEFAULT_WIDTH_RATIO  1
 | 
			
		||||
#define DEFAULT_HEIGHT_RATIO 1
 | 
			
		||||
private:
 | 
			
		||||
  static bool sGPUlayerpresent;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Qcom specific Native Window perform operations
 | 
			
		||||
 */
 | 
			
		||||
enum {
 | 
			
		||||
    NATIVE_WINDOW_SET_BUFFERS_SIZE        = 0x10000000,
 | 
			
		||||
    NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY = 0x20000000,
 | 
			
		||||
    NATIVE_WINDOW_SET_S3D_FORMAT          = 0x40000000,
 | 
			
		||||
    NATIVE_WINDOW_SET_PIXEL_ASPECT_RATIO  = 0x80000000,
 | 
			
		||||
public:
 | 
			
		||||
  static void checkforGPULayer(const hwc_layer_list_t* list);
 | 
			
		||||
  static bool isUpdatingFB(int compositionType);
 | 
			
		||||
  static int qcomuiClearRegion(Region region, EGLDisplay dpy);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Layer Attributes
 | 
			
		||||
 */
 | 
			
		||||
enum eLayerAttrib {
 | 
			
		||||
    LAYER_UPDATE_STATUS,
 | 
			
		||||
    LAYER_ASYNCHRONOUS_STATUS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Layer Flags
 | 
			
		||||
 */
 | 
			
		||||
enum {
 | 
			
		||||
    LAYER_UPDATING     = 1<<0,
 | 
			
		||||
    LAYER_ASYNCHRONOUS = 1<<1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Flags set by the layer and sent to HWC
 | 
			
		||||
 */
 | 
			
		||||
enum {
 | 
			
		||||
    HWC_LAYER_NOT_UPDATING      = 0x00000002,
 | 
			
		||||
    HWC_LAYER_ASYNCHRONOUS      = 0x00000004,
 | 
			
		||||
    HWC_COMP_BYPASS             = 0x10000000,
 | 
			
		||||
    HWC_USE_EXT_ONLY            = 0x20000000, //Layer displayed on external only
 | 
			
		||||
    HWC_USE_EXT_BLOCK           = 0x40000000, //Layer displayed on external only
 | 
			
		||||
    HWC_BYPASS_RESERVE_0        = 0x00000010,
 | 
			
		||||
    HWC_BYPASS_RESERVE_1        = 0x00000020,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Events to the Display HAL perform function
 | 
			
		||||
   As of now used for external display related such as
 | 
			
		||||
   connect, disconnect, orientation, video started etc.,
 | 
			
		||||
   */
 | 
			
		||||
enum {
 | 
			
		||||
    EVENT_EXTERNAL_DISPLAY,     // External display on/off Event
 | 
			
		||||
    EVENT_VIDEO_OVERLAY,        // Video Overlay start/stop Event
 | 
			
		||||
    EVENT_ORIENTATION_CHANGE,   // Orientation Change Event
 | 
			
		||||
    EVENT_OVERLAY_STATE_CHANGE, // Overlay State Change Event
 | 
			
		||||
    EVENT_OPEN_SECURE_START,    // Start of secure session setup config by stagefright
 | 
			
		||||
    EVENT_OPEN_SECURE_END,      // End of secure session setup config by stagefright
 | 
			
		||||
    EVENT_CLOSE_SECURE_START,   // Start of secure session teardown config
 | 
			
		||||
    EVENT_CLOSE_SECURE_END,     // End of secure session teardown config
 | 
			
		||||
    EVENT_RESET_POSTBUFFER,     // Reset post framebuffer mutex
 | 
			
		||||
    EVENT_WAIT_POSTBUFFER,      // Wait until post framebuffer returns
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Video information sent to framebuffer HAl
 | 
			
		||||
// used for handling UI mirroring.
 | 
			
		||||
enum {
 | 
			
		||||
    VIDEO_OVERLAY_ENDED = 0,
 | 
			
		||||
    VIDEO_2D_OVERLAY_STARTED,
 | 
			
		||||
    VIDEO_3D_OVERLAY_STARTED
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Information about overlay state change
 | 
			
		||||
enum {
 | 
			
		||||
    OVERLAY_STATE_CHANGE_START = 0,
 | 
			
		||||
    OVERLAY_STATE_CHANGE_END
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Structure to hold the buffer geometry
 | 
			
		||||
 */
 | 
			
		||||
struct qBufGeometry {
 | 
			
		||||
    int width;
 | 
			
		||||
    int height;
 | 
			
		||||
    int format;
 | 
			
		||||
    void set(int w, int h, int f) {
 | 
			
		||||
        width = w;
 | 
			
		||||
        height = h;
 | 
			
		||||
        format = f;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
class QCBaseLayer
 | 
			
		||||
{
 | 
			
		||||
    //    int mS3DFormat;
 | 
			
		||||
    int32_t mComposeS3DFormat;
 | 
			
		||||
    public:
 | 
			
		||||
    QCBaseLayer()
 | 
			
		||||
    {
 | 
			
		||||
        mComposeS3DFormat = 0;
 | 
			
		||||
    }
 | 
			
		||||
    enum { // S3D formats
 | 
			
		||||
        eS3D_SIDE_BY_SIDE   = 0x10000,
 | 
			
		||||
        eS3D_TOP_BOTTOM     = 0x20000
 | 
			
		||||
    };
 | 
			
		||||
    /*
 | 
			
		||||
       virtual status_t setStereoscopic3DFormat(int format) { mS3DFormat = format; return 0; }
 | 
			
		||||
       virtual int getStereoscopic3DFormat() const { return mS3DFormat; }
 | 
			
		||||
       */
 | 
			
		||||
    void setS3DComposeFormat (int32_t hints)
 | 
			
		||||
    {
 | 
			
		||||
        if (hints & HWC_HINT_DRAW_S3D_SIDE_BY_SIDE)
 | 
			
		||||
            mComposeS3DFormat = eS3D_SIDE_BY_SIDE;
 | 
			
		||||
        else if (hints & HWC_HINT_DRAW_S3D_TOP_BOTTOM)
 | 
			
		||||
            mComposeS3DFormat = eS3D_TOP_BOTTOM;
 | 
			
		||||
        else
 | 
			
		||||
            mComposeS3DFormat = 0;
 | 
			
		||||
    }
 | 
			
		||||
    int32_t needsS3DCompose () const { return mComposeS3DFormat; }
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Function to check if the allocated buffer is of the correct size.
 | 
			
		||||
 * Reallocate the buffer with the correct size, if the size doesn't
 | 
			
		||||
 * match
 | 
			
		||||
 *
 | 
			
		||||
 * @param: handle of the allocated buffer
 | 
			
		||||
 * @param: requested size for the buffer
 | 
			
		||||
 * @param: usage flags
 | 
			
		||||
 *
 | 
			
		||||
 * return 0 on success
 | 
			
		||||
 */
 | 
			
		||||
int checkBuffer(native_handle_t *buffer_handle, int size, int usage);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if the format is supported by the GPU.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: format to check
 | 
			
		||||
 *
 | 
			
		||||
 * @return true if the format is supported by the GPU.
 | 
			
		||||
 */
 | 
			
		||||
bool isGPUSupportedFormat(int format);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gets the number of arguments required for this operation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: operation whose argument count is required.
 | 
			
		||||
 *
 | 
			
		||||
 * @return -EINVAL if the operation is invalid.
 | 
			
		||||
 */
 | 
			
		||||
int getNumberOfArgsForOperation(int operation);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if memory needs to be reallocated for this buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: Geometry of the current buffer.
 | 
			
		||||
 * @param: Required Geometry.
 | 
			
		||||
 * @param: Geometry of the updated buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @return True if a memory reallocation is required.
 | 
			
		||||
 */
 | 
			
		||||
bool needNewBuffer(const qBufGeometry currentGeometry,
 | 
			
		||||
                   const qBufGeometry requiredGeometry,
 | 
			
		||||
                   const qBufGeometry updatedGeometry);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Update the geometry of this buffer without reallocation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: buffer whose geometry needs to be updated.
 | 
			
		||||
 * @param: Updated buffer geometry
 | 
			
		||||
 */
 | 
			
		||||
int updateBufferGeometry(sp<GraphicBuffer> buffer, const qBufGeometry bufGeometry);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Update the S3D format of this buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: buffer whosei S3D format needs to be updated.
 | 
			
		||||
 * @param: Updated buffer S3D format
 | 
			
		||||
 */
 | 
			
		||||
int updateBufferS3DFormat(sp<GraphicBuffer> buffer, const int s3dFormat);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Updates the flags for the layer
 | 
			
		||||
 *
 | 
			
		||||
 * @param: Attribute
 | 
			
		||||
 * @param: Identifies if the attribute was enabled or disabled.
 | 
			
		||||
 * @param: current Layer flags.
 | 
			
		||||
 *
 | 
			
		||||
 * @return: Flags for the layer
 | 
			
		||||
 */
 | 
			
		||||
int updateLayerQcomFlags(eLayerAttrib attribute, bool enable, int& currentFlags);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gets the per frame HWC flags for this layer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: current hwcl flags
 | 
			
		||||
 * @param: current layerFlags
 | 
			
		||||
 *
 | 
			
		||||
 * @return: the per frame flags.
 | 
			
		||||
 */
 | 
			
		||||
int getPerFrameFlags(int hwclFlags, int layerFlags);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if FB is updated by this composition type
 | 
			
		||||
 *
 | 
			
		||||
 * @param: composition type
 | 
			
		||||
 * @return: true if FB is updated, false if not
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
bool isUpdatingFB(HWCCompositionType compositionType);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Clear region implementation for C2D/MDP versions.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: region to be cleared
 | 
			
		||||
 * @param: EGL Display
 | 
			
		||||
 * @param: EGL Surface
 | 
			
		||||
 *
 | 
			
		||||
 * @return 0 on success
 | 
			
		||||
 */
 | 
			
		||||
int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Handles the externalDisplay event
 | 
			
		||||
 * HDMI has highest priority compared to WifiDisplay
 | 
			
		||||
 * Based on the current and the new display event, decides the
 | 
			
		||||
 * external display to be enabled
 | 
			
		||||
 *
 | 
			
		||||
 * @param: newEvent - new external event
 | 
			
		||||
 * @param: currEvent - currently enabled external event
 | 
			
		||||
 * @return: external display to be enabled
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
external_display_type handleEventHDMI(external_display_type disp, int value,
 | 
			
		||||
                                      external_display_type currDispType);
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if layers need to be dumped based on system property "debug.sf.dump"
 | 
			
		||||
 * for raw dumps and "debug.sf.dump.png" for png dumps.
 | 
			
		||||
 *
 | 
			
		||||
 * For example, to dump 25 frames in raw format, do,
 | 
			
		||||
 *     adb shell setprop debug.sf.dump 25
 | 
			
		||||
 * Layers are dumped in a time-stamped location: /data/sfdump*.
 | 
			
		||||
 *
 | 
			
		||||
 * To dump 10 frames in png format, do,
 | 
			
		||||
 *     adb shell setprop debug.sf.dump.png 10
 | 
			
		||||
 * To dump another 25 or so frames in raw format, do,
 | 
			
		||||
 *     adb shell setprop debug.sf.dump 26
 | 
			
		||||
 *
 | 
			
		||||
 * To turn off logcat logging of layer-info, set both properties to 0,
 | 
			
		||||
 *     adb shell setprop debug.sf.dump.png 0
 | 
			
		||||
 *     adb shell setprop debug.sf.dump 0
 | 
			
		||||
 *
 | 
			
		||||
 * @return: true if layers need to be dumped (or logcat-ed).
 | 
			
		||||
 */
 | 
			
		||||
bool needToDumpLayers();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Dumps a layer's info into logcat and its buffer into raw/png files.
 | 
			
		||||
 *
 | 
			
		||||
 * @param: moduleCompositionType - Composition type set in hwcomposer module.
 | 
			
		||||
 * @param: listFlags - Flags used in hwcomposer's list.
 | 
			
		||||
 * @param: layerIndex - Index of layer being dumped.
 | 
			
		||||
 * @param: hwLayers - Address of hwc_layer_t to log and dump.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
void dumpLayer(int moduleCompositionType, int listFlags, size_t layerIndex,
 | 
			
		||||
               hwc_layer_t hwLayers[]);
 | 
			
		||||
 | 
			
		||||
bool needsAspectRatio (int wRatio, int hRatio);
 | 
			
		||||
void applyPixelAspectRatio (int wRatio, int hRatio, int orientation, int fbWidth,
 | 
			
		||||
                            int fbHeight, Rect& visibleRect, GLfloat vertices[][2]);
 | 
			
		||||
 | 
			
		||||
#endif // INCLUDE_LIBQCOM_UI
 | 
			
		||||
}//namespace qdutils
 | 
			
		||||
#endif /* end of include guard: QCOM_UTIL_H*/
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user