upload android base code part4

This commit is contained in:
August 2018-08-08 17:00:29 +08:00
parent b9e30e05b1
commit 78ea2404cd
23455 changed files with 5250148 additions and 0 deletions

View file

@ -0,0 +1,39 @@
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
# b/24171136 many files not compiling with clang/llvm yet
LOCAL_CLANG := false
LOCAL_MODULE := libqdutils
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := $(common_libs) libui libbinder libqservice
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdutils\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := display_config.h mdp_version.h
LOCAL_SRC_FILES := profiler.cpp mdp_version.cpp \
idle_invalidator.cpp \
comptype.cpp qd_utils.cpp \
cb_utils.cpp display_config.cpp \
cb_swap_rect.cpp
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
# b/24171136 many files not compiling with clang/llvm yet
LOCAL_CLANG := false
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := qdMetaData.h
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := qdMetaData.cpp
LOCAL_CFLAGS := $(common_flags)
LOCAL_CFLAGS += -DLOG_TAG=\"DisplayMetaData\"
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libqdMetaData
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2014, The Linux Foundation. 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 The Linux Foundation or 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 "cb_swap_rect.h"
ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::cb_swap_rect);
namespace qdutils {
cb_swap_rect:: cb_swap_rect(){
swap_rect_feature_on = false ;
}
void cb_swap_rect::setSwapRectFeature_on( bool value){
swap_rect_feature_on = value ;
}
bool cb_swap_rect::checkSwapRectFeature_on(){
return swap_rect_feature_on;
}
};

View file

@ -0,0 +1,51 @@
/* Copyright (c) 2014, The Linux Foundation. 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 copyrigh
* 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 The Linux Foundation 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.
*/
#ifndef CB_SWAP_RECT
#define CB_SWAP_RECT
#include <stdint.h>
#include <utils/Singleton.h>
#include <cutils/log.h>
using namespace android;
namespace qdutils {
enum {
HWC_SKIP_HWC_COMPOSITION = 0x00040000,
};
class cb_swap_rect : public Singleton <cb_swap_rect>
{
bool swap_rect_feature_on;
public :
cb_swap_rect();
void setSwapRectFeature_on( bool value);
bool checkSwapRectFeature_on();
};
} // namespace qdutils
#endif

View file

@ -0,0 +1,101 @@
/* Copyright (c) 2013, The Linux Foundation. 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 copyrigh
* 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 The Linux Foundation 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 "cb_utils.h"
#include "cb_swap_rect.h"
#include <ui/Region.h>
/* get union of two rects into 3rd rect */
void getUnion(hwc_rect_t& rect1,hwc_rect_t& rect2, hwc_rect_t& irect) {
irect.left = min(rect1.left, rect2.left);
irect.top = min(rect1.top, rect2.top);
irect.right = max(rect1.right, rect2.right);
irect.bottom = max(rect1.bottom, rect2.bottom);
}
using namespace android;
using namespace qhwc;
namespace qdutils {
int CBUtils::getuiClearRegion(hwc_display_contents_1_t* list,
hwc_rect_t &clearWormholeRect, LayerProp *layerProp) {
size_t last = list->numHwLayers - 1;
hwc_rect_t fbFrame = list->hwLayers[last].displayFrame;
Rect fbFrameRect(fbFrame.left,fbFrame.top,fbFrame.right,fbFrame.bottom);
Region wormholeRegion(fbFrameRect);
if(cb_swap_rect::getInstance().checkSwapRectFeature_on() == true){
wormholeRegion.set(0,0);
for(size_t i = 0 ; i < last; i++) {
if(((list->hwLayers[i].blending == HWC_BLENDING_NONE) &&
(list->hwLayers[i].planeAlpha == 0xFF)) ||
!(layerProp[i].mFlags & HWC_COPYBIT) ||
(list->hwLayers[i].flags & HWC_SKIP_HWC_COMPOSITION))
continue ;
hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
Rect tmpRect(displayFrame.left,displayFrame.top,
displayFrame.right,displayFrame.bottom);
wormholeRegion.set(tmpRect);
}
}else{
for (size_t i = 0 ; i < last; i++) {
// need to take care only in per pixel blending.
// Restrict calculation only for copybit layers.
if((list->hwLayers[i].blending != HWC_BLENDING_NONE) ||
(list->hwLayers[i].planeAlpha != 0xFF) ||
!(layerProp[i].mFlags & HWC_COPYBIT))
continue ;
hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
Rect tmpRect(displayFrame.left,displayFrame.top,displayFrame.right,
displayFrame.bottom);
Region tmpRegion(tmpRect);
wormholeRegion.subtractSelf(wormholeRegion.intersect(tmpRegion));
}
}
if(wormholeRegion.isEmpty()){
return 0;
}
//TO DO :- 1. remove union and call clear for each rect.
Region::const_iterator it = wormholeRegion.begin();
Region::const_iterator const end = wormholeRegion.end();
while (it != end) {
const Rect& r = *it++;
hwc_rect_t tmpWormRect = {r.left,r.top,r.right,r.bottom};
int dst_w = clearWormholeRect.right - clearWormholeRect.left;
int dst_h = clearWormholeRect.bottom - clearWormholeRect.top;
if (!(dst_w || dst_h))
clearWormholeRect = tmpWormRect;
else
getUnion(clearWormholeRect, tmpWormRect, clearWormholeRect);
}
return 1;
}
}//namespace qdutils

View file

@ -0,0 +1,44 @@
/* Copyright (c) 2013, The Linux Foundation. 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 copyrigh
* 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 The Linux Foundation 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.
*/
#ifndef CB_UTIL_H
#define CB_UTIL_H
#include "hwc_utils.h"
using namespace qhwc;
namespace qdutils {
class CBUtils {
public:
static int getuiClearRegion(hwc_display_contents_1_t* list,
hwc_rect_t &clearWormholeRec,
LayerProp *layerProp);
};
}//namespace qdutils
#endif /* end of include guard: CB_UTIL_H*/

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2013, The Linux Foundation. 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 The Linux Foundation or 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<comptype.h>
//Instanticate the QCCompositionType Singleton
ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::QCCompositionType);

View file

@ -0,0 +1,81 @@
/*
* Copyright (C) 2012-2013, The Linux Foundation. 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 The Linux Foundation or 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.
*/
#ifndef INCLUDE_LIBQCOM_COMPTYPES
#define INCLUDE_LIBQCOM_COMPTYPES
#include <stdint.h>
#include <utils/Singleton.h>
#include <cutils/properties.h>
using namespace android;
namespace qdutils {
// Enum containing the supported composition types
enum {
COMPOSITION_TYPE_GPU = 0,
COMPOSITION_TYPE_MDP = 0x1,
COMPOSITION_TYPE_C2D = 0x2,
COMPOSITION_TYPE_CPU = 0x4,
COMPOSITION_TYPE_DYN = 0x8
};
/* This class caches the composition type
*/
class QCCompositionType : public Singleton <QCCompositionType>
{
public:
QCCompositionType();
~QCCompositionType() { }
int getCompositionType() {return mCompositionType;}
private:
int mCompositionType;
};
inline QCCompositionType::QCCompositionType()
{
char property[PROPERTY_VALUE_MAX];
mCompositionType = COMPOSITION_TYPE_GPU;
if (property_get("debug.composition.type", property, "gpu") > 0) {
if ((strncmp(property, "mdp", 3)) == 0) {
mCompositionType = COMPOSITION_TYPE_MDP;
} else if ((strncmp(property, "c2d", 3)) == 0) {
mCompositionType = COMPOSITION_TYPE_C2D;
} else if ((strncmp(property, "dyn", 3)) == 0) {
#ifdef USE_MDP3
mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_MDP;
#else
mCompositionType = COMPOSITION_TYPE_DYN | COMPOSITION_TYPE_C2D;
#endif
}
}
}
}; //namespace qdutils
#endif //INCLUDE_LIBQCOM_COMPTYPES

View file

@ -0,0 +1,182 @@
/*
* Copyright (c) 2013-2014 The Linux Foundation. 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 The Linux Foundation. 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 <display_config.h>
#include <QServiceUtils.h>
using namespace android;
using namespace qService;
namespace qdutils {
int isExternalConnected(void) {
int ret;
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
if(binder != NULL) {
err = binder->dispatch(IQService::CHECK_EXTERNAL_STATUS,
&inParcel , &outParcel);
}
if(err) {
ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
ret = err;
} else {
ret = outParcel.readInt32();
}
return ret;
}
int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr) {
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
inParcel.writeInt32(dpy);
if(binder != NULL) {
err = binder->dispatch(IQService::GET_DISPLAY_ATTRIBUTES,
&inParcel, &outParcel);
}
if(!err) {
dpyattr.vsync_period = outParcel.readInt32();
dpyattr.xres = outParcel.readInt32();
dpyattr.yres = outParcel.readInt32();
dpyattr.xdpi = outParcel.readFloat();
dpyattr.ydpi = outParcel.readFloat();
dpyattr.panel_type = (char) outParcel.readInt32();
} else {
ALOGE("%s: Failed to get display attributes err=%d", __FUNCTION__, err);
}
return err;
}
int setHSIC(int dpy, const HSICData_t& hsic_data) {
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
inParcel.writeInt32(dpy);
inParcel.writeInt32(hsic_data.hue);
inParcel.writeFloat(hsic_data.saturation);
inParcel.writeInt32(hsic_data.intensity);
inParcel.writeFloat(hsic_data.contrast);
if(binder != NULL) {
err = binder->dispatch(IQService::SET_HSIC_DATA, &inParcel, &outParcel);
}
if(err)
ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
return err;
}
int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
inParcel.writeInt32(dpy);
if(binder != NULL) {
err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION,
&inParcel, &outParcel);
}
if(!err) {
rect.left = outParcel.readInt32();
rect.top = outParcel.readInt32();
rect.right = outParcel.readInt32();
rect.bottom = outParcel.readInt32();
} else {
ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d",
__FUNCTION__, dpy, err);
}
return err;
}
int setViewFrame(int dpy, int l, int t, int r, int b) {
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
inParcel.writeInt32(dpy);
inParcel.writeInt32(l);
inParcel.writeInt32(t);
inParcel.writeInt32(r);
inParcel.writeInt32(b);
if(binder != NULL) {
err = binder->dispatch(IQService::SET_VIEW_FRAME,
&inParcel, &outParcel);
}
if(err)
ALOGE("%s: Failed to set view frame for dpy %d err=%d",
__FUNCTION__, dpy, err);
return err;
}
int setSecondaryDisplayStatus(int dpy, uint32_t status) {
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
inParcel.writeInt32(dpy);
inParcel.writeInt32(status);
if(binder != NULL) {
err = binder->dispatch(IQService::SET_SECONDARY_DISPLAY_STATUS,
&inParcel, &outParcel);
}
if(err)
ALOGE("%s: Failed for dpy %d status = %d err=%d", __FUNCTION__, dpy,
status, err);
return err;
}
int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) {
status_t err = (status_t) FAILED_TRANSACTION;
sp<IQService> binder = getBinder();
Parcel inParcel, outParcel;
inParcel.writeInt32(op);
inParcel.writeInt32(refreshRate);
if(binder != NULL) {
err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE,
&inParcel, &outParcel);
}
if(err)
ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err);
return err;
}
}; //namespace
// ----------------------------------------------------------------------------
// Screen refresh for native daemons linking dynamically to libqdutils
// ----------------------------------------------------------------------------
extern "C" int refreshScreen() {
int ret = 0;
ret = screenRefresh();
return ret;
}

View file

@ -0,0 +1,107 @@
/*
* Copyright (c) 2013 The Linux Foundation. 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 The Linux Foundation. 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 <gralloc_priv.h>
#include <qdMetaData.h>
#include <mdp_version.h>
#include <hardware/hwcomposer.h>
// This header is for clients to use to set/get global display configuration
// The functions in this header run in the client process and wherever necessary
// do a binder call to HWC to get/set data.
// Only primary and external displays are supported here.
// WiFi/virtual displays are not supported.
namespace qdutils {
/* TODO: Have all the common enums that need be exposed to clients and which
* are also needed in hwc defined here. Remove such definitions we have in
* hwc_utils.h
*/
// Use this enum to specify the dpy parameters where needed
enum {
DISPLAY_PRIMARY = 0,
DISPLAY_EXTERNAL,
DISPLAY_VIRTUAL,
};
// External Display states - used in setSecondaryDisplayStatus()
// To be consistent with the same defined in hwc_utils.h
enum {
EXTERNAL_OFFLINE = 0,
EXTERNAL_ONLINE,
EXTERNAL_PAUSE,
EXTERNAL_RESUME,
};
enum {
DISABLE_METADATA_DYN_REFRESH_RATE = 0,
ENABLE_METADATA_DYN_REFRESH_RATE,
SET_BINDER_DYN_REFRESH_RATE,
};
// Display Attributes that are available to clients of this library
// Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
struct DisplayAttributes_t {
uint32_t vsync_period; //nanoseconds
uint32_t xres;
uint32_t yres;
float xdpi;
float ydpi;
char panel_type;
};
// Check if external display is connected. Useful to check before making
// calls for external displays
// Returns 1 if connected, 0 if disconnected, negative values on errors
int isExternalConnected(void);
// Get display vsync period which is in nanoseconds
// i.e vsync_period = 1000000000l / fps
// Returns 0 on success, negative values on errors
int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr);
// Set HSIC data on a given display ID
// Returns 0 on success, negative values on errors
int setHSIC(int dpy, const HSICData_t& hsic_data);
// get the active visible region for the display
// Returns 0 on success, negative values on errors
int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect);
// set the view frame information in hwc context from surfaceflinger
int setViewFrame(int dpy, int l, int t, int r, int b);
// Set the secondary display status(pause/resume/offline etc.,)
int setSecondaryDisplayStatus(int dpy, uint32_t status);
// Enable/Disable/Set refresh rate dynamically
int configureDynRefreshRate(uint32_t op, uint32_t refreshRate);
}; //namespace

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2012, The Linux Foundation. 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 The Linux Foundation 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 "idle_invalidator.h"
#include <unistd.h>
#include <poll.h>
#include <string.h>
#include <fcntl.h>
#include <cutils/properties.h>
#define II_DEBUG 0
#define IDLE_NOTIFY_PATH "/sys/devices/virtual/graphics/fb0/idle_notify"
#define IDLE_TIME_PATH "/sys/devices/virtual/graphics/fb0/idle_time"
static const char *threadName = "IdleInvalidator";
InvalidatorHandler IdleInvalidator::mHandler = NULL;
android::sp<IdleInvalidator> IdleInvalidator::sInstance(0);
IdleInvalidator::IdleInvalidator(): Thread(false), mHwcContext(0),
mTimeoutEventFd(-1) {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
}
IdleInvalidator::~IdleInvalidator() {
if(mTimeoutEventFd >= 0) {
close(mTimeoutEventFd);
}
}
int IdleInvalidator::init(InvalidatorHandler reg_handler, void* user_data) {
mHandler = reg_handler;
mHwcContext = user_data;
// Open a sysfs node to receive the timeout notification from driver.
mTimeoutEventFd = open(IDLE_NOTIFY_PATH, O_RDONLY);
if (mTimeoutEventFd < 0) {
ALOGE ("%s:not able to open %s node %s",
__FUNCTION__, IDLE_NOTIFY_PATH, strerror(errno));
return -1;
}
int defaultIdleTime = 70; //ms
char property[PROPERTY_VALUE_MAX] = {0};
if((property_get("debug.mdpcomp.idletime", property, NULL) > 0)) {
defaultIdleTime = atoi(property);
}
if(not setIdleTimeout(defaultIdleTime)) {
close(mTimeoutEventFd);
mTimeoutEventFd = -1;
return -1;
}
//Triggers the threadLoop to run, if not already running.
run(threadName, android::PRIORITY_LOWEST);
return 0;
}
bool IdleInvalidator::setIdleTimeout(const uint32_t& timeout) {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s timeout %d",
__FUNCTION__, timeout);
// Open a sysfs node to send the timeout value to driver.
int fd = open(IDLE_TIME_PATH, O_WRONLY);
if (fd < 0) {
ALOGE ("%s:Unable to open %s node %s",
__FUNCTION__, IDLE_TIME_PATH, strerror(errno));
return false;
}
char strSleepTime[64];
snprintf(strSleepTime, sizeof(strSleepTime), "%d", timeout);
// Notify driver about the timeout value
ssize_t len = pwrite(fd, strSleepTime, strlen(strSleepTime), 0);
if(len < -1) {
ALOGE ("%s:Unable to write into %s node %s",
__FUNCTION__, IDLE_TIME_PATH, strerror(errno));
close(fd);
return false;
}
close(fd);
return true;
}
bool IdleInvalidator::threadLoop() {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
struct pollfd pFd;
pFd.fd = mTimeoutEventFd;
if (pFd.fd >= 0)
pFd.events = POLLPRI | POLLERR;
// Poll for an timeout event from driver
int err = poll(&pFd, 1, -1);
if(err > 0) {
if (pFd.revents & POLLPRI) {
char data[64];
// Consume the node by reading it
ssize_t len = pread(pFd.fd, data, 64, 0);
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s Idle Timeout fired len %zd",
__FUNCTION__, len);
mHandler((void*)mHwcContext);
}
}
return true;
}
int IdleInvalidator::readyToRun() {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
return 0; /*NO_ERROR*/
}
void IdleInvalidator::onFirstRef() {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
}
IdleInvalidator *IdleInvalidator::getInstance() {
ALOGD_IF(II_DEBUG, "IdleInvalidator::%s", __FUNCTION__);
if(sInstance.get() == NULL)
sInstance = new IdleInvalidator();
return sInstance.get();
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2012, The Linux Foundation. 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 The Linux Foundation 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.
*/
#ifndef INCLUDE_IDLEINVALIDATOR
#define INCLUDE_IDLEINVALIDATOR
#include <cutils/log.h>
#include <utils/threads.h>
#include <gr.h>
typedef void (*InvalidatorHandler)(void*);
class IdleInvalidator : public android::Thread {
IdleInvalidator();
void *mHwcContext;
int mTimeoutEventFd;
static InvalidatorHandler mHandler;
static android::sp<IdleInvalidator> sInstance;
public:
~IdleInvalidator();
/* init timer obj */
int init(InvalidatorHandler reg_handler, void* user_data);
bool setIdleTimeout(const uint32_t& timeout);
/*Overrides*/
virtual bool threadLoop();
virtual int readyToRun();
virtual void onFirstRef();
static IdleInvalidator *getInstance();
};
#endif // INCLUDE_IDLEINVALIDATOR

View file

@ -0,0 +1,507 @@
/*
* Copyright (c) 2012-2014, The Linux Foundation. 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 The Linux Foundation 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 <linux/msm_mdp.h>
#include "mdp_version.h"
#include "qd_utils.h"
#define DEBUG 0
ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::MDPVersion);
namespace qdutils {
#define TOKEN_PARAMS_DELIM "="
// chip variants have same major number and minor numbers usually vary
// for e.g., MDSS_MDP_HW_REV_101 is 0x10010000
// 1001 - major number
// 0000 - minor number
// 8x26 v1 minor number is 0000
// v2 minor number is 0001 etc..
#ifndef MDSS_MDP_HW_REV_100
#define MDSS_MDP_HW_REV_100 0x10000000 //8974 v1
#endif
#ifndef MDSS_MDP_HW_REV_101
#define MDSS_MDP_HW_REV_101 0x10010000 //8x26
#endif
#ifndef MDSS_MDP_HW_REV_102
#define MDSS_MDP_HW_REV_102 0x10020000 //8974 v2
#endif
#ifndef MDSS_MDP_HW_REV_103
#define MDSS_MDP_HW_REV_103 0x10030000 //8084
#endif
#ifndef MDSS_MDP_HW_REV_104
#define MDSS_MDP_HW_REV_104 0x10040000 //Unused
#endif
#ifndef MDSS_MDP_HW_REV_105
#define MDSS_MDP_HW_REV_105 0x10050000 //8994
#endif
#ifndef MDSS_MDP_HW_REV_106
#define MDSS_MDP_HW_REV_106 0x10060000 //8x16
#endif
#ifndef MDSS_MDP_HW_REV_107
#define MDSS_MDP_HW_REV_107 0x10070000 //Unused
#endif
#ifndef MDSS_MDP_HW_REV_108
#define MDSS_MDP_HW_REV_108 0x10080000 //8x39 & 8x36
#endif
#ifndef MDSS_MDP_HW_REV_109
#define MDSS_MDP_HW_REV_109 0x10090000 //8994 v2
#endif
#ifndef MDSS_MDP_HW_REV_110
#define MDSS_MDP_HW_REV_110 0x100a0000 //8992
#endif
#ifndef MDSS_MDP_HW_REV_200
#define MDSS_MDP_HW_REV_200 0x20000000 //8092
#endif
#ifndef MDSS_MDP_HW_REV_206
#define MDSS_MDP_HW_REV_206 0x20060000 //Future
#endif
MDPVersion::MDPVersion()
{
mMDPVersion = MDSS_V5;
mMdpRev = 0;
mRGBPipes = 0;
mVGPipes = 0;
mDMAPipes = 0;
mFeatures = 0;
mMDPUpscale = 1;
mMDPDownscale = 1;
mMacroTileEnabled = false;
mLowBw = 0;
mHighBw = 0;
mSourceSplit = false;
mSourceSplitAlways = false;
mRGBHasNoScalar = false;
mRotDownscale = false;
mBlendStages = 4; //min no. of stages supported by MDP.
// this is the default limit of mixer unless driver reports it.
// For resolutions beyond this, we use dual mixer/ping pong split.
mMaxMixerWidth = 2048;
// Default width of MDSS SSPP. For layer resolutions beyond this, we drive
// using two SSPP's.
mMaxPipeWidth = 2048;
updatePanelInfo();
if(!updateSysFsInfo()) {
ALOGE("Unable to read display sysfs node");
}
if (mMdpRev == MDP_V3_0_4){
mMDPVersion = MDP_V3_0_4;
}
else if (mMdpRev == MDP_V3_0_5){
mMDPVersion = MDP_V3_0_5;
}
mHasOverlay = false;
if((mMDPVersion >= MDP_V4_0) ||
(mMDPVersion == MDP_V_UNKNOWN) ||
(mMDPVersion == MDP_V3_0_4) ||
(mMDPVersion == MDP_V3_0_5))
mHasOverlay = true;
if(!updateSplitInfo()) {
ALOGE("Unable to read display split node");
}
}
MDPVersion::~MDPVersion() {
close(mFd);
}
int MDPVersion::tokenizeParams(char *inputParams, const char *delim,
char* tokenStr[], int *idx) {
char *tmp_token = NULL;
char *temp_ptr;
int index = 0;
if (!inputParams) {
return -1;
}
tmp_token = strtok_r(inputParams, delim, &temp_ptr);
while (tmp_token != NULL) {
tokenStr[index++] = tmp_token;
tmp_token = strtok_r(NULL, " ", &temp_ptr);
}
*idx = index;
return 0;
}
// This function reads the sysfs node to read the primary panel type
// and updates information accordingly
void MDPVersion::updatePanelInfo() {
FILE *displayDeviceFP = NULL;
FILE *panelInfoNodeFP = NULL;
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
const char *strCmdPanel = "mipi dsi cmd panel";
const char *strVideoPanel = "mipi dsi video panel";
const char *strLVDSPanel = "lvds panel";
const char *strEDPPanel = "edp panel";
displayDeviceFP = fopen("/sys/class/graphics/fb0/msm_fb_type", "r");
if(displayDeviceFP){
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
displayDeviceFP);
if(strncmp(fbType, strCmdPanel, strlen(strCmdPanel)) == 0) {
mPanelInfo.mType = MIPI_CMD_PANEL;
}
else if(strncmp(fbType, strVideoPanel, strlen(strVideoPanel)) == 0) {
mPanelInfo.mType = MIPI_VIDEO_PANEL;
}
else if(strncmp(fbType, strLVDSPanel, strlen(strLVDSPanel)) == 0) {
mPanelInfo.mType = LVDS_PANEL;
}
else if(strncmp(fbType, strEDPPanel, strlen(strEDPPanel)) == 0) {
mPanelInfo.mType = EDP_PANEL;
}
fclose(displayDeviceFP);
} else {
ALOGE("Unable to read Primary Panel Information");
}
panelInfoNodeFP = fopen("/sys/class/graphics/fb0/msm_fb_panel_info", "r");
if(panelInfoNodeFP){
size_t len = PAGE_SIZE;
ssize_t read;
char *readLine = (char *) malloc (len);
char property[PROPERTY_VALUE_MAX];
while((read = getline((char **)&readLine, &len,
panelInfoNodeFP)) != -1) {
int token_ct=0;
char *tokens[10];
memset(tokens, 0, sizeof(tokens));
if(!tokenizeParams(readLine, TOKEN_PARAMS_DELIM, tokens,
&token_ct)) {
if(!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
mPanelInfo.mPartialUpdateEnable = atoi(tokens[1]);
ALOGI("PartialUpdate status: %s",
mPanelInfo.mPartialUpdateEnable? "Enabled" :
"Disabled");
}
if(!strncmp(tokens[0], "xstart", strlen("xstart"))) {
mPanelInfo.mLeftAlign = atoi(tokens[1]);
ALOGI("Left Align: %d", mPanelInfo.mLeftAlign);
}
if(!strncmp(tokens[0], "walign", strlen("walign"))) {
mPanelInfo.mWidthAlign = atoi(tokens[1]);
ALOGI("Width Align: %d", mPanelInfo.mWidthAlign);
}
if(!strncmp(tokens[0], "ystart", strlen("ystart"))) {
mPanelInfo.mTopAlign = atoi(tokens[1]);
ALOGI("Top Align: %d", mPanelInfo.mTopAlign);
}
if(!strncmp(tokens[0], "halign", strlen("halign"))) {
mPanelInfo.mHeightAlign = atoi(tokens[1]);
ALOGI("Height Align: %d", mPanelInfo.mHeightAlign);
}
if(!strncmp(tokens[0], "min_w", strlen("min_w"))) {
mPanelInfo.mMinROIWidth = atoi(tokens[1]);
ALOGI("Min ROI Width: %d", mPanelInfo.mMinROIWidth);
}
if(!strncmp(tokens[0], "min_h", strlen("min_h"))) {
mPanelInfo.mMinROIHeight = atoi(tokens[1]);
ALOGI("Min ROI Height: %d", mPanelInfo.mMinROIHeight);
}
if(!strncmp(tokens[0], "roi_merge", strlen("roi_merge"))) {
mPanelInfo.mNeedsROIMerge = atoi(tokens[1]);
ALOGI("Needs ROI Merge: %d", mPanelInfo.mNeedsROIMerge);
}
if(!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
mPanelInfo.mDynFpsSupported = atoi(tokens[1]);
ALOGI("Dynamic Fps: %s", mPanelInfo.mDynFpsSupported ?
"Enabled" : "Disabled");
}
if(!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
mPanelInfo.mMinFps = atoi(tokens[1]);
ALOGI("Min Panel fps: %d", mPanelInfo.mMinFps);
}
if(!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
mPanelInfo.mMaxFps = atoi(tokens[1]);
ALOGI("Max Panel fps: %d", mPanelInfo.mMaxFps);
}
}
}
if((property_get("persist.hwc.pubypass", property, 0) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
mPanelInfo.mPartialUpdateEnable = 0;
ALOGI("PartialUpdate disabled by property");
}
fclose(panelInfoNodeFP);
free(readLine);
} else {
ALOGE("Failed to open msm_fb_panel_info node");
}
}
// This function reads the sysfs node to read MDP capabilities
// and parses and updates information accordingly.
bool MDPVersion::updateSysFsInfo() {
FILE *sysfsFd;
size_t len = PAGE_SIZE;
ssize_t read;
char *line = NULL;
char sysfsPath[255];
memset(sysfsPath, 0, sizeof(sysfsPath));
snprintf(sysfsPath , sizeof(sysfsPath),
"/sys/class/graphics/fb0/mdp/caps");
char property[PROPERTY_VALUE_MAX];
bool enableMacroTile = false;
if((property_get("persist.hwc.macro_tile_enable", property, NULL) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
enableMacroTile = true;
}
sysfsFd = fopen(sysfsPath, "rb");
if (sysfsFd == NULL) {
ALOGE("%s: sysFsFile file '%s' not found",
__FUNCTION__, sysfsPath);
return false;
} else {
line = (char *) malloc(len);
while((read = getline(&line, &len, sysfsFd)) != -1) {
int index=0;
char *tokens[10];
memset(tokens, 0, sizeof(tokens));
// parse the line and update information accordingly
if(!tokenizeParams(line, TOKEN_PARAMS_DELIM, tokens, &index)) {
if(!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
mMdpRev = atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "rgb_pipes", strlen("rgb_pipes"))) {
mRGBPipes = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "vig_pipes", strlen("vig_pipes"))) {
mVGPipes = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
mDMAPipes = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "blending_stages",
strlen("blending_stages"))) {
mBlendStages = (uint8_t)atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "max_downscale_ratio",
strlen("max_downscale_ratio"))) {
mMDPDownscale = atoi(tokens[1]);
}
else if(!strncmp(tokens[0], "max_upscale_ratio",
strlen("max_upscale_ratio"))) {
mMDPUpscale = atoi(tokens[1]);
} else if(!strncmp(tokens[0], "max_bandwidth_low",
strlen("max_bandwidth_low"))) {
mLowBw = atol(tokens[1]);
} else if(!strncmp(tokens[0], "max_bandwidth_high",
strlen("max_bandwidth_high"))) {
mHighBw = atol(tokens[1]);
} else if(!strncmp(tokens[0], "max_mixer_width",
strlen("max_mixer_width"))) {
mMaxMixerWidth = atoi(tokens[1]);
} else if(!strncmp(tokens[0], "max_pipe_width",
strlen("max_pipe_width"))) {
mMaxPipeWidth = atoi(tokens[1]);
} else if(!strncmp(tokens[0], "features", strlen("features"))) {
for(int i=1; i<index;i++) {
if(!strncmp(tokens[i], "bwc", strlen("bwc"))) {
mFeatures |= MDP_BWC_EN;
} else if(!strncmp(tokens[i], "decimation",
strlen("decimation"))) {
mFeatures |= MDP_DECIMATION_EN;
} else if(!strncmp(tokens[i], "tile_format",
strlen("tile_format"))) {
if(enableMacroTile)
mMacroTileEnabled = true;
} else if(!strncmp(tokens[i], "src_split",
strlen("src_split"))) {
mSourceSplit = true;
} else if(!strncmp(tokens[i], "non_scalar_rgb",
strlen("non_scalar_rgb"))) {
mRGBHasNoScalar = true;
} else if(!strncmp(tokens[i], "rotator_downscale",
strlen("rotator_downscale"))) {
mRotDownscale = true;
}
}
}
}
}
free(line);
fclose(sysfsFd);
}
if(mMDPVersion >= qdutils::MDP_V4_2 and mMDPVersion < qdutils::MDSS_V5) {
mRotDownscale = true;
}
if(mSourceSplit) {
memset(sysfsPath, 0, sizeof(sysfsPath));
snprintf(sysfsPath , sizeof(sysfsPath),
"/sys/class/graphics/fb0/msm_fb_src_split_info");
sysfsFd = fopen(sysfsPath, "rb");
if (sysfsFd == NULL) {
ALOGE("%s: Opening file %s failed with error %s", __FUNCTION__,
sysfsPath, strerror(errno));
return false;
} else {
line = (char *) malloc(len);
if((read = getline(&line, &len, sysfsFd)) != -1) {
if(!strncmp(line, "src_split_always",
strlen("src_split_always"))) {
mSourceSplitAlways = true;
}
}
free(line);
fclose(sysfsFd);
}
}
ALOGD_IF(DEBUG, "%s: mMDPVersion: %d mMdpRev: %x mRGBPipes:%d,"
"mVGPipes:%d", __FUNCTION__, mMDPVersion, mMdpRev,
mRGBPipes, mVGPipes);
ALOGD_IF(DEBUG, "%s:mDMAPipes:%d \t mMDPDownscale:%d, mFeatures:%d",
__FUNCTION__, mDMAPipes, mMDPDownscale, mFeatures);
ALOGD_IF(DEBUG, "%s:mLowBw: %lu mHighBw: %lu", __FUNCTION__, mLowBw,
mHighBw);
return true;
}
// This function reads the sysfs node to read MDP capabilities
// and parses and updates information accordingly.
bool MDPVersion::updateSplitInfo() {
if(mMDPVersion >= MDSS_V5) {
char split[64] = {0};
FILE* fp = fopen("/sys/class/graphics/fb0/msm_fb_split", "r");
if(fp){
//Format "left right" space as delimiter
if(fread(split, sizeof(char), 64, fp)) {
split[sizeof(split) - 1] = '\0';
mSplit.mLeft = atoi(split);
ALOGI_IF(mSplit.mLeft, "Left Split=%d", mSplit.mLeft);
char *rght = strpbrk(split, " ");
if(rght)
mSplit.mRight = atoi(rght + 1);
ALOGI_IF(mSplit.mRight, "Right Split=%d", mSplit.mRight);
}
} else {
ALOGE("Failed to open mdss_fb_split node");
return false;
}
if(fp)
fclose(fp);
}
return true;
}
bool MDPVersion::hasMinCropWidthLimitation() const {
return mMdpRev <= MDSS_MDP_HW_REV_102;
}
bool MDPVersion::supportsDecimation() {
return mFeatures & MDP_DECIMATION_EN;
}
uint32_t MDPVersion::getMaxMDPDownscale() {
return mMDPDownscale;
}
uint32_t MDPVersion::getMaxMDPUpscale() {
return mMDPUpscale;
}
bool MDPVersion::supportsBWC() {
// BWC - Bandwidth Compression
return (mFeatures & MDP_BWC_EN);
}
bool MDPVersion::supportsMacroTile() {
// MACRO TILE support
return mMacroTileEnabled;
}
bool MDPVersion::isSrcSplit() const {
return mSourceSplit;
}
bool MDPVersion::isSrcSplitAlways() const {
return mSourceSplitAlways;
}
bool MDPVersion::isRGBScalarSupported() const {
return (!mRGBHasNoScalar);
}
bool MDPVersion::is8x26() {
return (mMdpRev >= MDSS_MDP_HW_REV_101 and
mMdpRev < MDSS_MDP_HW_REV_102);
}
bool MDPVersion::is8x74v2() {
return (mMdpRev >= MDSS_MDP_HW_REV_102 and
mMdpRev < MDSS_MDP_HW_REV_103);
}
bool MDPVersion::is8084() {
return (mMdpRev >= MDSS_MDP_HW_REV_103 and
mMdpRev < MDSS_MDP_HW_REV_104);
}
bool MDPVersion::is8092() {
return (mMdpRev >= MDSS_MDP_HW_REV_200 and
mMdpRev < MDSS_MDP_HW_REV_206);
}
bool MDPVersion::is8994() {
return ((mMdpRev >= MDSS_MDP_HW_REV_105 and
mMdpRev < MDSS_MDP_HW_REV_106) or
(mMdpRev >= MDSS_MDP_HW_REV_109 and
mMdpRev < MDSS_MDP_HW_REV_110));
}
bool MDPVersion::is8x16() {
return (mMdpRev >= MDSS_MDP_HW_REV_106 and
mMdpRev < MDSS_MDP_HW_REV_107);
}
bool MDPVersion::is8x39() {
return (mMdpRev >= MDSS_MDP_HW_REV_108 and
mMdpRev < MDSS_MDP_HW_REV_109);
}
}; //namespace qdutils

View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2012-2013, The Linux Foundation. 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 The Linux Foundation 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.
*/
#ifndef INCLUDE_LIBQCOMUTILS_MDPVER
#define INCLUDE_LIBQCOMUTILS_MDPVER
#include <stdint.h>
#include <utils/Singleton.h>
#include <cutils/properties.h>
/* This class gets the MSM type from the soc info
*/
using namespace android;
namespace qdutils {
// These panel definitions are available at mdss_mdp.h which is internal header
// file and is not available at <linux/mdss_mdp.h>.
// ToDo: once it is available at linux/mdss_mdp.h, these below definitions can
// be removed.
enum mdp_version {
MDP_V_UNKNOWN = 0,
MDP_V2_2 = 220,
MDP_V3_0 = 300,
MDP_V3_0_3 = 303,
MDP_V3_0_4 = 304,
MDP_V3_0_5 = 305,
MDP_V3_1 = 310,
MDP_V4_0 = 400,
MDP_V4_1 = 410,
MDP_V4_2 = 420,
MDP_V4_3 = 430,
MDP_V4_4 = 440,
MDSS_V5 = 500,
};
#define NO_PANEL '0'
#define MDDI_PANEL '1'
#define EBI2_PANEL '2'
#define LCDC_PANEL '3'
#define EXT_MDDI_PANEL '4'
#define TV_PANEL '5'
#define DTV_PANEL '7'
#define MIPI_VIDEO_PANEL '8'
#define MIPI_CMD_PANEL '9'
#define WRITEBACK_PANEL 'a'
#define LVDS_PANEL 'b'
#define EDP_PANEL 'c'
class MDPVersion;
struct Split {
int mLeft;
int mRight;
Split() : mLeft(0), mRight(0){}
int left() { return mLeft; }
int right() { return mRight; }
friend class MDPVersion;
};
struct PanelInfo {
char mType; // Smart or Dumb
int mPartialUpdateEnable; // Partial update feature
int mLeftAlign; // ROI left alignment restriction
int mWidthAlign; // ROI width alignment restriction
int mTopAlign; // ROI top alignment restriction
int mHeightAlign; // ROI height alignment restriction
int mMinROIWidth; // Min width needed for ROI
int mMinROIHeight; // Min height needed for ROI
bool mNeedsROIMerge; // Merge ROI's of both the DSI's
bool mDynFpsSupported; // Panel Supports dyn fps
uint32_t mMinFps; // Min fps supported by panel
uint32_t mMaxFps; // Max fps supported by panel
PanelInfo() : mType(NO_PANEL), mPartialUpdateEnable(0),
mLeftAlign(0), mWidthAlign(0), mTopAlign(0), mHeightAlign(0),
mMinROIWidth(0), mMinROIHeight(0), mNeedsROIMerge(false),
mDynFpsSupported(0), mMinFps(0), mMaxFps(0) {}
friend class MDPVersion;
};
class MDPVersion : public Singleton <MDPVersion>
{
public:
MDPVersion();
~MDPVersion();
int getMDPVersion() {return mMDPVersion;}
char getPanelType() {return mPanelInfo.mType;}
bool hasOverlay() {return mHasOverlay;}
uint8_t getTotalPipes() {
return (uint8_t)(mRGBPipes + mVGPipes + mDMAPipes);
}
uint8_t getRGBPipes() { return mRGBPipes; }
uint8_t getVGPipes() { return mVGPipes; }
uint8_t getDMAPipes() { return mDMAPipes; }
uint8_t getBlendStages() { return mBlendStages; }
bool supportsDecimation();
uint32_t getMaxMDPDownscale();
uint32_t getMaxMDPUpscale();
bool supportsBWC();
bool supportsMacroTile();
int getLeftSplit() { return mSplit.left(); }
int getRightSplit() { return mSplit.right(); }
bool isPartialUpdateEnabled() { return mPanelInfo.mPartialUpdateEnable; }
int getLeftAlign() { return mPanelInfo.mLeftAlign; }
int getWidthAlign() { return mPanelInfo.mWidthAlign; }
int getTopAlign() { return mPanelInfo.mTopAlign; }
int getHeightAlign() { return mPanelInfo.mHeightAlign; }
int getMinROIWidth() { return mPanelInfo.mMinROIWidth; }
int getMinROIHeight() { return mPanelInfo.mMinROIHeight; }
bool needsROIMerge() { return mPanelInfo.mNeedsROIMerge; }
unsigned long getLowBw() { return mLowBw; }
unsigned long getHighBw() { return mHighBw; }
bool isRotDownscaleEnabled() { return mRotDownscale; }
bool isDynFpsSupported() { return mPanelInfo.mDynFpsSupported; }
uint32_t getMinFpsSupported() { return mPanelInfo.mMinFps; }
uint32_t getMaxFpsSupported() { return mPanelInfo.mMaxFps; }
uint32_t getMaxMixerWidth() const { return mMaxMixerWidth; }
uint32_t getMaxPipeWidth() const { return mMaxPipeWidth; }
bool hasMinCropWidthLimitation() const;
bool isSrcSplit() const;
bool isSrcSplitAlways() const;
bool isRGBScalarSupported() const;
bool is8x26();
bool is8x74v2();
bool is8084();
bool is8092();
bool is8994();
bool is8x16();
bool is8x39();
private:
bool updateSysFsInfo();
void updatePanelInfo();
bool updateSplitInfo();
int tokenizeParams(char *inputParams, const char *delim,
char* tokenStr[], int *idx);
int mFd;
int mMDPVersion;
bool mHasOverlay;
uint32_t mMdpRev;
uint8_t mRGBPipes;
uint8_t mVGPipes;
uint8_t mDMAPipes;
uint8_t mBlendStages;
uint32_t mFeatures;
uint32_t mMDPDownscale;
uint32_t mMDPUpscale;
bool mMacroTileEnabled;
Split mSplit;
PanelInfo mPanelInfo;
unsigned long mLowBw; //kbps
unsigned long mHighBw; //kbps
bool mSourceSplit;
//Additional property on top of source split
bool mSourceSplitAlways;
bool mRGBHasNoScalar;
bool mRotDownscale;
uint32_t mMaxMixerWidth; //maximum x-res of a given mdss mixer.
uint32_t mMaxPipeWidth; //maximum x-res of the mdp pipe.
};
}; //namespace qdutils
#endif //INCLUDE_LIBQCOMUTILS_MDPVER

View file

@ -0,0 +1,196 @@
/*
* Copyright (c) 2011-2012, The Linux Foundation. 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 The Linux Foundation 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.
*/
#define LOG_NDDEBUG 0
#include <inttypes.h>
#include "profiler.h"
#ifdef DEBUG_CALC_FPS
ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::CalcFps) ;
namespace qdutils {
CalcFps::CalcFps() {
debug_fps_level = 0;
Init();
}
CalcFps::~CalcFps() {
}
void CalcFps::Init() {
char prop[PROPERTY_VALUE_MAX];
property_get("debug.gr.calcfps", prop, "0");
debug_fps_level = atoi(prop);
if (debug_fps_level > MAX_DEBUG_FPS_LEVEL) {
ALOGW("out of range value for debug.gr.calcfps, using 0");
debug_fps_level = 0;
}
ALOGD("DEBUG_CALC_FPS: %d", debug_fps_level);
populate_debug_fps_metadata();
}
void CalcFps::Fps() {
if (debug_fps_level > 0)
calc_fps(ns2us(systemTime()));
}
void CalcFps::populate_debug_fps_metadata(void)
{
char prop[PROPERTY_VALUE_MAX];
/*defaults calculation of fps to based on number of frames*/
property_get("debug.gr.calcfps.type", prop, "0");
debug_fps_metadata.type = (debug_fps_metadata_t::DfmType) atoi(prop);
/*defaults to 1000ms*/
property_get("debug.gr.calcfps.timeperiod", prop, "1000");
debug_fps_metadata.time_period = atoi(prop);
property_get("debug.gr.calcfps.period", prop, "10");
debug_fps_metadata.period = atoi(prop);
if (debug_fps_metadata.period > MAX_FPS_CALC_PERIOD_IN_FRAMES) {
debug_fps_metadata.period = MAX_FPS_CALC_PERIOD_IN_FRAMES;
}
/* default ignorethresh_us: 500 milli seconds */
property_get("debug.gr.calcfps.ignorethresh_us", prop, "500000");
debug_fps_metadata.ignorethresh_us = atoi(prop);
debug_fps_metadata.framearrival_steps =
(unsigned int)(debug_fps_metadata.ignorethresh_us / 16666);
if (debug_fps_metadata.framearrival_steps > MAX_FRAMEARRIVAL_STEPS) {
debug_fps_metadata.framearrival_steps = MAX_FRAMEARRIVAL_STEPS;
debug_fps_metadata.ignorethresh_us =
debug_fps_metadata.framearrival_steps * 16666;
}
/* 2ms margin of error for the gettimeofday */
debug_fps_metadata.margin_us = 2000;
for (unsigned int i = 0; i < MAX_FRAMEARRIVAL_STEPS; i++)
debug_fps_metadata.accum_framearrivals[i] = 0;
debug_fps_metadata.curr_frame = 0;
ALOGD("period: %u", debug_fps_metadata.period);
ALOGD("ignorethresh_us: %" PRId64, debug_fps_metadata.ignorethresh_us);
}
void CalcFps::print_fps(float fps)
{
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type)
ALOGD("FPS for last %d frames: %3.2f", debug_fps_metadata.period, fps);
else
ALOGD("FPS for last (%f ms, %d frames): %3.2f",
debug_fps_metadata.time_elapsed,
debug_fps_metadata.curr_frame, fps);
debug_fps_metadata.curr_frame = 0;
debug_fps_metadata.time_elapsed = 0.0;
if (debug_fps_level > 1) {
ALOGD("Frame Arrival Distribution:");
for (unsigned int i = 0;
i < ((debug_fps_metadata.framearrival_steps / 6) + 1);
i++) {
ALOGD("%" PRId64" %" PRId64" %" PRId64" %" PRId64" %" PRId64" %" PRId64,
debug_fps_metadata.accum_framearrivals[i*6],
debug_fps_metadata.accum_framearrivals[i*6+1],
debug_fps_metadata.accum_framearrivals[i*6+2],
debug_fps_metadata.accum_framearrivals[i*6+3],
debug_fps_metadata.accum_framearrivals[i*6+4],
debug_fps_metadata.accum_framearrivals[i*6+5]);
}
/* We are done with displaying, now clear the stats */
for (unsigned int i = 0;
i < debug_fps_metadata.framearrival_steps;
i++)
debug_fps_metadata.accum_framearrivals[i] = 0;
}
return;
}
void CalcFps::calc_fps(nsecs_t currtime_us)
{
static nsecs_t oldtime_us = 0;
nsecs_t diff = currtime_us - oldtime_us;
oldtime_us = currtime_us;
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type &&
diff > debug_fps_metadata.ignorethresh_us) {
return;
}
if (debug_fps_metadata.curr_frame < MAX_FPS_CALC_PERIOD_IN_FRAMES) {
debug_fps_metadata.framearrivals[debug_fps_metadata.curr_frame] = diff;
}
debug_fps_metadata.curr_frame++;
if (debug_fps_level > 1) {
unsigned int currstep =
(unsigned int)(diff + debug_fps_metadata.margin_us) / 16666;
if (currstep < debug_fps_metadata.framearrival_steps) {
debug_fps_metadata.accum_framearrivals[currstep-1]++;
}
}
if (debug_fps_metadata_t::DFM_FRAMES == debug_fps_metadata.type) {
if (debug_fps_metadata.curr_frame == debug_fps_metadata.period) {
/* time to calculate and display FPS */
nsecs_t sum = 0;
for (unsigned int i = 0; i < debug_fps_metadata.period; i++)
sum += debug_fps_metadata.framearrivals[i];
print_fps(float(float(debug_fps_metadata.period * 1000000) /
(float)sum));
}
}
else if (debug_fps_metadata_t::DFM_TIME == debug_fps_metadata.type) {
debug_fps_metadata.time_elapsed += (float)((float)diff/1000.0);
if (debug_fps_metadata.time_elapsed >= debug_fps_metadata.time_period) {
float fps = float(1000.0 * debug_fps_metadata.curr_frame/
debug_fps_metadata.time_elapsed);
print_fps(fps);
}
}
return;
}
};//namespace qomutils
#endif

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2011-2012, The Linux Foundation. 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 The Linux Foundation 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.
*/
#ifndef INCLUDE_PROFILER
#define INCLUDE_PROFILER
#include <stdio.h>
#include <utils/Singleton.h>
#include <cutils/properties.h>
#include <cutils/log.h>
#ifndef DEBUG_CALC_FPS
#define CALC_FPS() ((void)0)
#define CALC_INIT() ((void)0)
#else
#define CALC_FPS() qdutils::CalcFps::getInstance().Fps()
#define CALC_INIT() qdutils::CalcFps::getInstance().Init()
using namespace android;
namespace qdutils {
class CalcFps : public Singleton<CalcFps> {
public:
CalcFps();
~CalcFps();
void Init();
void Fps();
private:
static const unsigned int MAX_FPS_CALC_PERIOD_IN_FRAMES = 128;
static const unsigned int MAX_FRAMEARRIVAL_STEPS = 50;
static const unsigned int MAX_DEBUG_FPS_LEVEL = 2;
struct debug_fps_metadata_t {
/*fps calculation based on time or number of frames*/
enum DfmType {
DFM_FRAMES = 0,
DFM_TIME = 1,
};
DfmType type;
/* indicates how much time do we wait till we calculate FPS */
unsigned long time_period;
/*indicates how much time elapsed since we report fps*/
float time_elapsed;
/* indicates how many frames do we wait till we calculate FPS */
unsigned int period;
/* current frame, will go upto period, and then reset */
unsigned int curr_frame;
/* frame will arrive at a multiple of 16666 us at the display.
This indicates how many steps to consider for our calculations.
For example, if framearrival_steps = 10, then the frame that arrived
after 166660 us or more will be ignored.
*/
unsigned int framearrival_steps;
/* ignorethresh_us = framearrival_steps * 16666 */
nsecs_t ignorethresh_us;
/* used to calculate the actual frame arrival step, the times might not be
accurate
*/
unsigned int margin_us;
/* actual data storage */
nsecs_t framearrivals[MAX_FPS_CALC_PERIOD_IN_FRAMES];
nsecs_t accum_framearrivals[MAX_FRAMEARRIVAL_STEPS];
};
private:
void populate_debug_fps_metadata(void);
void print_fps(float fps);
void calc_fps(nsecs_t currtime_us);
private:
debug_fps_metadata_t debug_fps_metadata;
unsigned int debug_fps_level;
};
};//namespace qdutils
#endif
#endif // INCLUDE_PROFILER

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2012-2014, The Linux Foundation. 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 The Linux Foundation 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 <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <cutils/log.h>
#include <gralloc_priv.h>
#include <inttypes.h>
#include "qdMetaData.h"
int setMetaData(private_handle_t *handle, DispParamType paramType,
void *param) {
if (!handle) {
ALOGE("%s: Private handle is null!", __func__);
return -1;
}
if (handle->fd_metadata == -1) {
ALOGE("%s: Bad fd for extra data!", __func__);
return -1;
}
if (!param) {
ALOGE("%s: input param is null!", __func__);
return -1;
}
unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
handle->fd_metadata, 0);
if (base == reinterpret_cast<void*>(MAP_FAILED)) {
ALOGE("%s: mmap() failed: error is %s!", __func__, strerror(errno));
return -1;
}
MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
data->operation |= paramType;
switch (paramType) {
case PP_PARAM_HSIC:
memcpy((void *)&data->hsicData, param, sizeof(HSICData_t));
break;
case PP_PARAM_SHARPNESS:
data->sharpness = *((int32_t *)param);
break;
case PP_PARAM_VID_INTFC:
data->video_interface = *((int32_t *)param);
break;
case PP_PARAM_INTERLACED:
data->interlaced = *((int32_t *)param);
break;
case PP_PARAM_IGC:
memcpy((void *)&data->igcData, param, sizeof(IGCData_t));
break;
case PP_PARAM_SHARP2:
memcpy((void *)&data->Sharp2Data, param, sizeof(Sharp2Data_t));
break;
case PP_PARAM_TIMESTAMP:
data->timestamp = *((int64_t *)param);
break;
case UPDATE_BUFFER_GEOMETRY:
memcpy((void *)&data->bufferDim, param, sizeof(BufferDim_t));
break;
case UPDATE_REFRESH_RATE:
data->refreshrate = *((uint32_t *)param);
break;
case UPDATE_COLOR_SPACE:
data->colorSpace = *((ColorSpace_t *)param);
break;
case MAP_SECURE_BUFFER:
data->mapSecureBuffer = *((int32_t *)param);
break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
}
if(munmap(base, size))
ALOGE("%s: failed to unmap ptr %p, err %d", __func__, (void*)base,
errno);
return 0;
}

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2012-2014, The Linux Foundation. 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 The Linux Foundation 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.
*/
#ifndef _QDMETADATA_H
#define _QDMETADATA_H
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_IGC_LUT_ENTRIES 256
enum ColorSpace_t{
ITU_R_601,
ITU_R_601_FR,
ITU_R_709,
};
struct HSICData_t {
int32_t hue;
float saturation;
int32_t intensity;
float contrast;
};
struct Sharp2Data_t {
int32_t strength;
uint32_t edge_thr;
uint32_t smooth_thr;
uint32_t noise_thr;
};
struct IGCData_t{
uint16_t c0[MAX_IGC_LUT_ENTRIES];
uint16_t c1[MAX_IGC_LUT_ENTRIES];
uint16_t c2[MAX_IGC_LUT_ENTRIES];
};
struct BufferDim_t {
int32_t sliceWidth;
int32_t sliceHeight;
};
struct MetaData_t {
int32_t operation;
int32_t interlaced;
struct BufferDim_t bufferDim;
struct HSICData_t hsicData;
int32_t sharpness;
int32_t video_interface;
struct IGCData_t igcData;
struct Sharp2Data_t Sharp2Data;
int64_t timestamp;
uint32_t refreshrate;
enum ColorSpace_t colorSpace;
/* Gralloc sets PRIV_SECURE_BUFFER flag to inform that the buffers are from
* ION_SECURE. which should not be mapped. However, for GPU post proc
* feature, GFX needs to map this buffer, in the client context and in SF
* context, it should not. Hence to differentiate, add this metadata field
* for clients to set, and GPU will to read and know when to map the
* SECURE_BUFFER(ION) */
int32_t mapSecureBuffer;
};
enum DispParamType {
PP_PARAM_HSIC = 0x0001,
PP_PARAM_SHARPNESS = 0x0002,
PP_PARAM_INTERLACED = 0x0004,
PP_PARAM_VID_INTFC = 0x0008,
PP_PARAM_IGC = 0x0010,
PP_PARAM_SHARP2 = 0x0020,
PP_PARAM_TIMESTAMP = 0x0040,
UPDATE_BUFFER_GEOMETRY = 0x0080,
UPDATE_REFRESH_RATE = 0x0100,
UPDATE_COLOR_SPACE = 0x0200,
MAP_SECURE_BUFFER = 0x400,
};
struct private_handle_t;
int setMetaData(struct private_handle_t *handle, enum DispParamType paramType,
void *param);
#ifdef __cplusplus
}
#endif
#endif /* _QDMETADATA_H */

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 "qd_utils.h"
#define QD_UTILS_DEBUG 0
namespace qdutils {
int getHDMINode(void)
{
FILE *displayDeviceFP = NULL;
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
int j = 0;
for(j = 0; j < HWC_NUM_DISPLAY_TYPES; j++) {
snprintf (msmFbTypePath, sizeof(msmFbTypePath),
"/sys/class/graphics/fb%d/msm_fb_type", j);
displayDeviceFP = fopen(msmFbTypePath, "r");
if(displayDeviceFP) {
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
displayDeviceFP);
if(strncmp(fbType, "dtv panel", strlen("dtv panel")) == 0) {
ALOGD("%s: HDMI is at fb%d", __func__, j);
fclose(displayDeviceFP);
break;
}
fclose(displayDeviceFP);
} else {
ALOGD("%s: fb node %d not present", __func__, j);
}
}
if (j < HWC_NUM_DISPLAY_TYPES)
return j;
else
ALOGI("%s: No HDMI node on this device", __func__);
return -1;
}
int getEdidRawData(char *buffer)
{
int size;
int edidFile;
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
int node_id = getHDMINode();
if (node_id < 0) {
ALOGE("%s no HDMI node found", __func__);
return 0;
}
snprintf(msmFbTypePath, sizeof(msmFbTypePath),
"/sys/class/graphics/fb%d/edid_raw_data", node_id);
edidFile = open(msmFbTypePath, O_RDONLY, 0);
if (edidFile < 0) {
ALOGE("%s no edid raw data found", __func__);
return 0;
}
size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
close(edidFile);
return size;
}
/* Calculates the aspect ratio for based on src & dest */
void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
int srcHeight, hwc_rect_t& rect) {
int x =0, y =0;
if (srcWidth * destHeight > destWidth * srcHeight) {
srcHeight = destWidth * srcHeight / srcWidth;
srcWidth = destWidth;
} else if (srcWidth * destHeight < destWidth * srcHeight) {
srcWidth = destHeight * srcWidth / srcHeight;
srcHeight = destHeight;
} else {
srcWidth = destWidth;
srcHeight = destHeight;
}
if (srcWidth > destWidth) srcWidth = destWidth;
if (srcHeight > destHeight) srcHeight = destHeight;
x = (destWidth - srcWidth) / 2;
y = (destHeight - srcHeight) / 2;
ALOGD_IF(QD_UTILS_DEBUG, "%s: AS Position: x = %d, y = %d w = %d h = %d",
__FUNCTION__, x, y, srcWidth , srcHeight);
// Convert it back to hwc_rect_t
rect.left = x;
rect.top = y;
rect.right = srcWidth + rect.left;
rect.bottom = srcHeight + rect.top;
}
}; //namespace qdutils

View file

@ -0,0 +1,62 @@
/*
* Copyright (C) 2013, The Linux Foundation. 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 The Linux Foundation or 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.
*/
#ifndef _QD_UTIL_MISC_H
#define _QD_UTIL_MISC_H
#include <utils/threads.h>
#include <linux/fb.h>
#include <ctype.h>
#include <fcntl.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/resource.h>
#include <cutils/properties.h>
#include <hardware/hwcomposer.h>
namespace qdutils {
#define EDID_RAW_DATA_SIZE 640
enum qd_utils {
MAX_FRAME_BUFFER_NAME_SIZE = 128,
MAX_SYSFS_FILE_PATH = 255,
SUPPORTED_DOWNSCALE_AREA = (1920*1080)
};
int getHDMINode(void);
int getEdidRawData(char *buffer);
void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
int srcHeight, hwc_rect_t& rect);
}; //namespace qdutils
#endif