summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Qiu <junhai.qiu@intel.com>2014-09-10 18:33:00 -0700
committerEd Tam <etam@google.com>2014-09-12 17:48:55 -0700
commitaf3bf2227c951a59e2dcc44ab90790d247225375 (patch)
tree5d86ac2803d6552e9ce9e35010dff3237b41a9c3
parent9f04a62c6e8c91ebeb199986ae11fc5107492df2 (diff)
downloadhwcomposer-af3bf2227c951a59e2dcc44ab90790d247225375.tar.gz
support 480/576 mode.
Bug: 17391301 BZ: 222162 Change-Id: I96ac2695455723978f5a7c4fb5b5f74c4719580f Signed-off-by: Andy Qiu <junhai.qiu@intel.com>
-rwxr-xr-x[-rw-r--r--]common/base/Drm.cpp25
-rwxr-xr-x[-rw-r--r--]common/base/Drm.h1
-rwxr-xr-xcommon/base/HwcLayerList.cpp21
-rwxr-xr-x[-rw-r--r--]common/planes/DisplayPlane.cpp29
-rwxr-xr-x[-rw-r--r--]include/BufferManager.h2
-rwxr-xr-x[-rw-r--r--]include/DisplayPlane.h9
-rwxr-xr-x[-rw-r--r--]include/DisplayQuery.h1
-rwxr-xr-xips/anniedale/AnnOverlayPlane.cpp47
-rwxr-xr-xips/anniedale/AnnOverlayPlane.h5
-rwxr-xr-x[-rw-r--r--]ips/anniedale/AnnRGBPlane.cpp54
-rwxr-xr-x[-rw-r--r--]ips/anniedale/AnnRGBPlane.h5
-rwxr-xr-x[-rw-r--r--]ips/tangier/TngDisplayQuery.cpp26
-rwxr-xr-x[-rw-r--r--]platforms/merrifield_plus/PlatfBufferManager.cpp7
-rwxr-xr-x[-rw-r--r--]platforms/merrifield_plus/PlatfBufferManager.h2
14 files changed, 224 insertions, 10 deletions
diff --git a/common/base/Drm.cpp b/common/base/Drm.cpp
index 5239d0a..ada30cc 100644..100755
--- a/common/base/Drm.cpp
+++ b/common/base/Drm.cpp
@@ -467,6 +467,31 @@ bool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height)
return true;
}
+bool Drm::getDisplayResolution(int device, uint32_t& width, uint32_t& height)
+{
+ Mutex::Autolock _l(mLock);
+
+ int outputIndex = getOutputIndex(device);
+ if (outputIndex < 0) {
+ return false;
+ }
+
+ DrmOutput *output= &mOutputs[outputIndex];
+ if (output->connected == false) {
+ ELOGTRACE("device is not connected");
+ return false;
+ }
+
+ width = output->mode.hdisplay;
+ height = output->mode.vdisplay;
+
+ if (!width || !height) {
+ ELOGTRACE("invalid width or height");
+ return false;
+ }
+ return true;
+}
+
bool Drm::isConnected(int device)
{
Mutex::Autolock _l(mLock);
diff --git a/common/base/Drm.h b/common/base/Drm.h
index a50b17c..ff77ffd 100644..100755
--- a/common/base/Drm.h
+++ b/common/base/Drm.h
@@ -61,6 +61,7 @@ public:
int getDrmFd() const;
bool getModeInfo(int device, drmModeModeInfo& mode);
bool getPhysicalSize(int device, uint32_t& width, uint32_t& height);
+ bool getDisplayResolution(int device, uint32_t& width, uint32_t& height);
bool isSameDrmMode(drmModeModeInfoPtr mode, drmModeModeInfoPtr base) const;
int getPanelOrientation(int device);
diff --git a/common/base/HwcLayerList.cpp b/common/base/HwcLayerList.cpp
index 774a9e2..a6326fc 100755
--- a/common/base/HwcLayerList.cpp
+++ b/common/base/HwcLayerList.cpp
@@ -337,7 +337,13 @@ bool HwcLayerList::initialize()
rgbOverlayLayers.removeItemsAt(0);
}
- allocatePlanes();
+ if (!DisplayQuery::forceFbScaling(mDisplayIndex)) {
+ allocatePlanes();
+ } else {
+ // force GLES composition on all layers, then use GPU or hardware
+ // overlay to scale buffer to match display resolution
+ assignPrimaryPlane();
+ }
//dump();
return true;
@@ -589,7 +595,18 @@ bool HwcLayerList::assignPrimaryPlane()
bool HwcLayerList::assignPrimaryPlaneHelper(HwcLayer *hwcLayer, int zorder)
{
- ZOrderLayer *zlayer = addZOrderLayer(DisplayPlane::PLANE_PRIMARY, hwcLayer, zorder);
+ int type = DisplayPlane::PLANE_PRIMARY;
+ if (DisplayQuery::forceFbScaling(mDisplayIndex)) {
+ type = DisplayPlane::PLANE_OVERLAY;
+ // use overlay plane as primary plane. Color is converted to NV12 first then overlay
+ // hardware will perform scaling to display resolution.
+
+ // can use primary plane as well, but frame buffer needs to be scaled to match display resolution,
+ // (primary plane does not support RGB scaling). There is issue in DDK blit function (RGB scaling
+ // yields corrupt output)
+ }
+
+ ZOrderLayer *zlayer = addZOrderLayer(type, hwcLayer, zorder);
bool ok = attachPlanes();
if (!ok) {
removeZOrderLayer(zlayer);
diff --git a/common/planes/DisplayPlane.cpp b/common/planes/DisplayPlane.cpp
index 0056363..ce4a5f5 100644..100755
--- a/common/planes/DisplayPlane.cpp
+++ b/common/planes/DisplayPlane.cpp
@@ -17,6 +17,7 @@
#include <Hwcomposer.h>
#include <DisplayPlane.h>
#include <GraphicBuffer.h>
+#include <DisplayQuery.h>
namespace android {
namespace intel {
@@ -35,7 +36,12 @@ DisplayPlane::DisplayPlane(int index, int type, int disp)
mPlaneAlpha(0),
mBlending(HWC_BLENDING_NONE),
mCurrentDataBuffer(0),
- mUpdateMasks(0)
+ mUpdateMasks(0),
+ mForceScaling(false),
+ mDisplayWidth(0),
+ mDisplayHeight(0),
+ mScalingSource(0),
+ mScalingTarget(0)
{
CTRACE();
memset(&mPosition, 0, sizeof(mPosition));
@@ -105,6 +111,11 @@ void DisplayPlane::setPosition(int x, int y, int w, int h)
{
ALOGTRACE("Position = %d, %d - %dx%d", x, y, w, h);
+ if (mForceScaling) {
+ // set in assignToDevice
+ return;
+ }
+
if (mPosition.x != x || mPosition.y != y ||
mPosition.w != w || mPosition.h != h) {
mUpdateMasks |= PLANE_POSITION_CHANGED;
@@ -331,6 +342,22 @@ bool DisplayPlane::assignToDevice(int disp)
mPanelOrientation = drm->getPanelOrientation(mDevice);
+ mForceScaling = DisplayQuery::forceFbScaling(disp);
+ drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight);
+
+ if (mForceScaling) {
+ mModeInfo.hdisplay = mDisplayWidth;
+ mModeInfo.vdisplay = mDisplayHeight;
+ mPosition.x = 0;
+ mPosition.y = 0;
+ mPosition.w = mDisplayWidth;
+ mPosition.h = mDisplayHeight;
+ }
+ mDisplayCrop.x = 0;
+ mDisplayCrop.y = 0;
+ mDisplayCrop.w = mDisplayWidth;
+ mDisplayCrop.h = mDisplayHeight;
+
return true;
}
diff --git a/include/BufferManager.h b/include/BufferManager.h
index c9326bc..20dc634 100644..100755
--- a/include/BufferManager.h
+++ b/include/BufferManager.h
@@ -59,7 +59,7 @@ public:
uint32_t allocGrallocBuffer(uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
void freeGrallocBuffer(uint32_t handle);
- virtual bool convertRGBToNV12(uint32_t rgbHandle, uint32_t yuvHandle,
+ virtual bool blitGrallocBuffer(uint32_t srcHandle, uint32_t dstHandle,
crop_t& srcCrop, uint32_t async) = 0;
protected:
virtual DataBuffer* createDataBuffer(gralloc_module_t *module,
diff --git a/include/DisplayPlane.h b/include/DisplayPlane.h
index 190ef25..b394765 100644..100755
--- a/include/DisplayPlane.h
+++ b/include/DisplayPlane.h
@@ -146,6 +146,15 @@ protected:
uint32_t mUpdateMasks;
drmModeModeInfo mModeInfo;
int mPanelOrientation;
+
+protected:
+ bool mForceScaling;
+ uint32_t mDisplayWidth;
+ uint32_t mDisplayHeight;
+ crop_t mDisplayCrop;
+ uint32_t mScalingSource;
+ uint32_t mScalingTarget;
+
};
} // namespace intel
diff --git a/include/DisplayQuery.h b/include/DisplayQuery.h
index 185a25d..e3932cc 100644..100755
--- a/include/DisplayQuery.h
+++ b/include/DisplayQuery.h
@@ -25,6 +25,7 @@ public:
static bool isVideoFormat(uint32_t format);
static int getOverlayLumaStrideAlignment(uint32_t format);
static uint32_t queryNV12Format();
+ static bool forceFbScaling(int device);
};
} // namespace intel
diff --git a/ips/anniedale/AnnOverlayPlane.cpp b/ips/anniedale/AnnOverlayPlane.cpp
index 93524fc..dc5f2fd 100755
--- a/ips/anniedale/AnnOverlayPlane.cpp
+++ b/ips/anniedale/AnnOverlayPlane.cpp
@@ -21,6 +21,7 @@
#include <ips/anniedale/AnnOverlayPlane.h>
#include <ips/tangier/TngGrallocBuffer.h>
#include <khronos/openmax/OMX_IntelVideoExt.h>
+#include <DisplayQuery.h>
namespace android {
namespace intel {
@@ -42,6 +43,38 @@ AnnOverlayPlane::~AnnOverlayPlane()
CTRACE();
}
+bool AnnOverlayPlane::setDataBuffer(uint32_t handle)
+{
+ if (handle == 0) {
+ ELOGTRACE("handle == 0");
+ return true;
+ }
+
+ if (mForceScaling) {
+ BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
+ ssize_t index = mScalingBufferMap.indexOfKey(handle);
+ if (index < 0) {
+ mScalingTarget = bm->allocGrallocBuffer(
+ mSrcCrop.w,
+ mSrcCrop.h,
+ DisplayQuery::queryNV12Format(),
+ GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_VIDEO_ENCODER);
+ if (!mScalingTarget) {
+ ELOGTRACE("Failed to allocate gralloc buffer.");
+ return false;
+ }
+ mScalingBufferMap.add(handle, mScalingTarget);
+ } else {
+ mScalingTarget = mScalingBufferMap.valueAt(index);
+ }
+
+ mScalingSource = handle;
+ handle = mScalingTarget;
+ }
+
+ return DisplayPlane::setDataBuffer(handle);
+}
+
void AnnOverlayPlane::setZOrderConfig(ZOrderConfig& /* zorderConfig */,
void *nativeConfig)
{
@@ -70,6 +103,12 @@ void AnnOverlayPlane::setZOrderConfig(ZOrderConfig& /* zorderConfig */,
bool AnnOverlayPlane::reset()
{
+ while (!mScalingBufferMap.isEmpty()) {
+ uint32_t handle = mScalingBufferMap.valueAt(0);
+ Hwcomposer::getInstance().getBufferManager()->freeGrallocBuffer(handle);
+ mScalingBufferMap.removeItemsAt(0);
+ }
+
OverlayPlaneBase::reset();
if (mRotationBufProvider) {
mRotationBufProvider->reset();
@@ -592,6 +631,14 @@ bool AnnOverlayPlane::flip(void *ctx)
RETURN_FALSE_IF_NOT_INIT();
+ if (mForceScaling) {
+ BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
+ if (!bm->blitGrallocBuffer(mScalingSource, mScalingTarget, mSrcCrop, 0)) {
+ ELOGTRACE("Failed to blit RGB buffer to NV12.");
+ return false;
+ }
+ }
+
if (!DisplayPlane::flip(ctx)) {
ELOGTRACE("failed to flip display plane.");
return false;
diff --git a/ips/anniedale/AnnOverlayPlane.h b/ips/anniedale/AnnOverlayPlane.h
index df5f6eb..53235c4 100755
--- a/ips/anniedale/AnnOverlayPlane.h
+++ b/ips/anniedale/AnnOverlayPlane.h
@@ -32,6 +32,8 @@ public:
AnnOverlayPlane(int index, int disp);
virtual ~AnnOverlayPlane();
+ bool setDataBuffer(uint32_t handle);
+
virtual void setTransform(int transform);
virtual void setZOrderConfig(ZOrderConfig& config, void *nativeConfig);
@@ -67,6 +69,9 @@ protected:
bool mUseOverlayRotation;
// hardware context
struct intel_dc_plane_ctx mContext;
+
+private:
+ KeyedVector<uint32_t, uint32_t> mScalingBufferMap;
};
} // namespace intel
diff --git a/ips/anniedale/AnnRGBPlane.cpp b/ips/anniedale/AnnRGBPlane.cpp
index 9cb8af3..afc4480 100644..100755
--- a/ips/anniedale/AnnRGBPlane.cpp
+++ b/ips/anniedale/AnnRGBPlane.cpp
@@ -45,6 +45,30 @@ bool AnnRGBPlane::disable()
return enablePlane(false);
}
+bool AnnRGBPlane::reset()
+{
+ while (!mScalingBufferMap.isEmpty()) {
+ uint32_t handle = mScalingBufferMap.valueAt(0);
+ Hwcomposer::getInstance().getBufferManager()->freeGrallocBuffer(handle);
+ mScalingBufferMap.removeItemsAt(0);
+ }
+
+ return DisplayPlane::reset();
+}
+
+bool AnnRGBPlane::flip(void*)
+{
+ if (mForceScaling) {
+ BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
+ if (!bm->blitGrallocBuffer(mScalingSource, mScalingTarget, mDisplayCrop, 0)) {
+ ELOGTRACE("Failed to blit RGB buffer.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
void* AnnRGBPlane::getContext() const
{
CTRACE();
@@ -59,8 +83,34 @@ void AnnRGBPlane::setZOrderConfig(ZOrderConfig& /* config */, void * /* nativeCo
bool AnnRGBPlane::setDataBuffer(uint32_t handle)
{
if (!handle) {
- setFramebufferTarget(handle);
- return true;
+ if (!mForceScaling) {
+ setFramebufferTarget(handle);
+ return true;
+ } else {
+ ELOGTRACE("Invalid handle while scaling is required.");
+ return false;
+ }
+ }
+
+ if (mForceScaling) {
+ BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
+ ssize_t index = mScalingBufferMap.indexOfKey(handle);
+ if (index < 0) {
+ mScalingTarget = bm->allocGrallocBuffer(
+ mDisplayWidth,
+ mDisplayHeight,
+ HAL_PIXEL_FORMAT_RGBA_8888,
+ GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE);
+ if (!mScalingTarget) {
+ ELOGTRACE("Failed to allocate gralloc buffer.");
+ return false;
+ }
+ mScalingBufferMap.add(handle, mScalingTarget);
+ } else {
+ mScalingTarget = mScalingBufferMap.valueAt(index);
+ }
+ mScalingSource = handle;
+ handle = mScalingTarget;
}
TngGrallocBuffer tmpBuf(handle);
diff --git a/ips/anniedale/AnnRGBPlane.h b/ips/anniedale/AnnRGBPlane.h
index 6c9a46e..76ef53a 100644..100755
--- a/ips/anniedale/AnnRGBPlane.h
+++ b/ips/anniedale/AnnRGBPlane.h
@@ -34,7 +34,9 @@ public:
// hardware operations
bool enable();
bool disable();
+ bool reset();
bool isDisabled();
+ bool flip(void *ctx);
void postFlip();
void* getContext() const;
@@ -48,6 +50,9 @@ private:
void setFramebufferTarget(uint32_t handle);
protected:
struct intel_dc_plane_ctx mContext;
+
+private:
+ KeyedVector<uint32_t, uint32_t> mScalingBufferMap;
};
} // namespace intel
diff --git a/ips/tangier/TngDisplayQuery.cpp b/ips/tangier/TngDisplayQuery.cpp
index e2daa58..13350aa 100644..100755
--- a/ips/tangier/TngDisplayQuery.cpp
+++ b/ips/tangier/TngDisplayQuery.cpp
@@ -19,6 +19,7 @@
#include <hal_public.h>
#include <DisplayQuery.h>
#include <khronos/openmax/OMX_IntelVideoExt.h>
+#include <Hwcomposer.h>
namespace android {
@@ -57,6 +58,31 @@ uint32_t DisplayQuery::queryNV12Format()
return HAL_PIXEL_FORMAT_NV12;
}
+bool DisplayQuery::forceFbScaling(int device)
+{
+ // RGB planes don't support scaling. Panel fitter can be used to scale frame buffer to device's resolution
+ // if scaling factor is less than 1.5. Otherwise, GPU scaling is needed on RGB buffer, or hardware overlay
+ // scaling is needed on NV12 buffer
+
+ // this needs to work together with kernel driver. Panel fitter needs to be disabled if scaling factor is greater
+ // than 1.5
+
+ uint32_t width, height;
+ if (!Hwcomposer::getInstance().getDrm()->getDisplayResolution(device, width, height)) {
+ return false;
+ }
+
+ if (DEFAULT_DRM_FB_WIDTH / (float)width > 1.5) {
+ return true;
+ }
+
+ if (DEFAULT_DRM_FB_HEIGHT / (float)height > 1.5) {
+ return true;
+ }
+
+ return false;
+}
+
} // namespace intel
} // namespace android
diff --git a/platforms/merrifield_plus/PlatfBufferManager.cpp b/platforms/merrifield_plus/PlatfBufferManager.cpp
index 9ff12a7..764c47b 100644..100755
--- a/platforms/merrifield_plus/PlatfBufferManager.cpp
+++ b/platforms/merrifield_plus/PlatfBufferManager.cpp
@@ -58,13 +58,13 @@ BufferMapper* PlatfBufferManager::createBufferMapper(gralloc_module_t *module,
buffer);
}
-bool PlatfBufferManager::convertRGBToNV12(uint32_t rgbHandle, uint32_t yuvHandle,
+bool PlatfBufferManager::blitGrallocBuffer(uint32_t srcHandle, uint32_t dstHandle,
crop_t& srcCrop, uint32_t async)
{
IMG_gralloc_module_public_t *imgGrallocModule = (IMG_gralloc_module_public_t *) mGrallocModule;
- if (imgGrallocModule->Blit(imgGrallocModule, (buffer_handle_t)rgbHandle,
- (buffer_handle_t)yuvHandle,
+ if (imgGrallocModule->Blit(imgGrallocModule, (buffer_handle_t)srcHandle,
+ (buffer_handle_t)dstHandle,
srcCrop.w, srcCrop.h, srcCrop.x,
srcCrop.y, 0, async)) {
ELOGTRACE("Blit failed");
@@ -73,5 +73,6 @@ bool PlatfBufferManager::convertRGBToNV12(uint32_t rgbHandle, uint32_t yuvHandle
return true;
}
+
} // namespace intel
} // namespace android
diff --git a/platforms/merrifield_plus/PlatfBufferManager.h b/platforms/merrifield_plus/PlatfBufferManager.h
index 0eb8c64..11ff950 100644..100755
--- a/platforms/merrifield_plus/PlatfBufferManager.h
+++ b/platforms/merrifield_plus/PlatfBufferManager.h
@@ -34,7 +34,7 @@ protected:
DataBuffer* createDataBuffer(gralloc_module_t *module, uint32_t handle);
BufferMapper* createBufferMapper(gralloc_module_t *module,
DataBuffer& buffer);
- bool convertRGBToNV12(uint32_t rgbHandle, uint32_t yuvHandle,
+ bool blitGrallocBuffer(uint32_t srcHandle, uint32_t dstHandle,
crop_t& srcCrop, uint32_t async);
};