liboverlay: Refactor, bug-fixes, upgrade.

* Fix memory leak during copying pipe objects.
* Remove unused / unnecessary code.
* setMemoryId API is merged with queueBuffer.
* setParameter API is setTransform now.
* Rotator upgraded to:
  --Allow different rotator hardware types.
  --Remove dependency on MDP code.
  --Allocate memory only during first playback,
  close when the associated pipe is closed.
* Have single commit implementation.
* Include new format types.
* Remove WAIT and CHANNEL enums and usage. Replace BypassPipe with
  GenericPipe. Client expected to set alignments and parameters.
  Add transform combination enums.
* Allow APIs to be called in any order. Do transform calcs in commit.
  Move ext type setter and getter functions.
* Add calculations for 180 transform.
* Add secure session support in rotator
* Implement all rotations in terms of H flip, V flip and 90 rotation.

Change-Id: I34a9a2a0f1255b3467a0abbaa254d0b584e901ce
This commit is contained in:
Naseer Ahmed
2012-07-20 09:05:53 -07:00
committed by Brian Muramatsu
parent 8831816879
commit f48aef64b2
28 changed files with 1697 additions and 3203 deletions

View File

@@ -277,7 +277,6 @@ static void *hdmi_ui_loop(void *ptr)
ovutils::PipeArgs parg(mdpFlags, ovutils::PipeArgs parg(mdpFlags,
ovutils::OVERLAY_TRANSFORM_0, ovutils::OVERLAY_TRANSFORM_0,
whf, whf,
ovutils::WAIT,
ovutils::ZORDER_0, ovutils::ZORDER_0,
ovutils::IS_FG_OFF, ovutils::IS_FG_OFF,
ovutils::ROT_FLAG_ENABLED); ovutils::ROT_FLAG_ENABLED);

View File

@@ -9,6 +9,6 @@ LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay libgenlock \
libqdutils libqdutils
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"hwcomposer\" LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"hwcomposer\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := hwc.cpp hwc_overlay.cpp hwc_utils.cpp LOCAL_SRC_FILES := hwc.cpp hwc_video.cpp hwc_utils.cpp
include $(BUILD_SHARED_LIBRARY) include $(BUILD_SHARED_LIBRARY)

View File

@@ -23,6 +23,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include "hwc_utils.h" #include "hwc_utils.h"
#include "hwc_video.h"
using namespace qhwc; using namespace qhwc;
@@ -65,19 +66,19 @@ static void hwc_registerProcs(struct hwc_composer_device* dev,
static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
{ {
hwc_context_t* ctx = (hwc_context_t*)(dev); hwc_context_t* ctx = (hwc_context_t*)(dev);
ctx->overlayInUse = false;
//Prepare is called after a vsync, so unlock previous buffers here.
ctx->qbuf->unlockAllPrevious();
if (LIKELY(list)) { if (LIKELY(list)) {
getLayerStats(ctx, list); getLayerStats(ctx, list);
cleanOverlays(ctx); if(VideoOverlay::prepare(ctx, list)) {
for (int i=list->numHwLayers-1; i >= 0 ; i--) { ctx->overlayInUse = true;
private_handle_t *hnd = //Nothing here
(private_handle_t *)list->hwLayers[i].handle; } else if (0) {
if (isSkipLayer(&list->hwLayers[i])) { //Other features
break; ctx->overlayInUse = true;
} else if(isYuvBuffer(hnd)) {
handleYUV(ctx,&list->hwLayers[i]);
} else {
list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
}
} }
} }
return 0; return 0;
@@ -91,21 +92,16 @@ static int hwc_set(hwc_composer_device_t *dev,
int ret = 0; int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev); hwc_context_t* ctx = (hwc_context_t*)(dev);
if (LIKELY(list)) { if (LIKELY(list)) {
for (size_t i=0; i<list->numHwLayers; i++) { VideoOverlay::draw(ctx, list);
if (list->hwLayers[i].flags & HWC_SKIP_LAYER) {
continue;
} else if (list->hwLayers[i].compositionType == HWC_OVERLAY) {
drawLayerUsingOverlay(ctx, &(list->hwLayers[i]));
}
}
//XXX: Handle vsync with FBIO_WAITFORVSYNC ioctl
//All other operations (including pan display) should be NOWAIT
EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur); EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
} else { } else {
//XXX: put in a wrapper for non overlay targets ctx->mOverlay->setState(ovutils::OV_CLOSED);
setOverlayState(ctx, ovutils::OV_CLOSED);
}
ctx->qbuf->unlockAllPrevious(); ctx->qbuf->unlockAllPrevious();
}
if(!ctx->overlayInUse)
ctx->mOverlay->setState(ovutils::OV_CLOSED);
return ret; return ret;
} }

View File

@@ -1,295 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hwc_utils.h"
#define FINAL_TRANSFORM_MASK 0x000F
namespace qhwc {
// Determine overlay state based on decoded video info
static ovutils::eOverlayState determineOverlayState(hwc_context_t* ctx,
uint32_t bypassLayer,
uint32_t format)
{
ovutils::eOverlayState state = ovutils::OV_CLOSED;
// Sanity check
if (!ctx) {
ALOGE("%s: NULL ctx", __FUNCTION__);
return state;
}
overlay::Overlay& ov = *(ctx->mOverlay);
state = ov.getState();
// If there are any bypassLayers, state is based on number of layers
if ((bypassLayer > 0) && (ctx->hdmiEnabled == EXT_TYPE_NONE)) {
if (bypassLayer == 1) {
state = ovutils::OV_BYPASS_1_LAYER;
} else if (bypassLayer == 2) {
state = ovutils::OV_BYPASS_2_LAYER;
} else if (bypassLayer == 3) {
state = ovutils::OV_BYPASS_3_LAYER;
}
return state;
}
// RGB is ambiguous for determining overlay state
if (ovutils::isRgb(ovutils::getMdpFormat(format))) {
return state;
}
// Content type is either 2D or 3D
uint32_t fmt3D = 0;//XXX: 3D - ovutils::getS3DFormat(format);
// Determine state based on the external display, content type, and hw type
if (ctx->hdmiEnabled == EXT_TYPE_HDMI) {
// External display is HDMI
if (fmt3D) {
// Content type is 3D
if (ovutils::is3DTV()) {
// TV panel type is 3D
state = ovutils::OV_3D_VIDEO_ON_3D_TV;
} else {
// TV panel type is 2D
state = ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV;
}
} else {
// Content type is 2D
if (ovutils::FrameBufferInfo::getInstance()->supportTrueMirroring()) {
// True UI mirroring is supported
state = ovutils::OV_2D_TRUE_UI_MIRROR;
} else {
// True UI mirroring is not supported
state = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
}
}
} else if (ctx->hdmiEnabled == EXT_TYPE_WIFI) {
// External display is Wifi (currently unsupported)
ALOGE("%s: WIFI external display is unsupported", __FUNCTION__);
return state;
} else {
// No external display (primary panel only)
if (fmt3D) {
// Content type is 3D
if (ovutils::usePanel3D()) {
// Primary panel type is 3D
state = ovutils::OV_3D_VIDEO_ON_3D_PANEL;
} else {
// Primary panel type is 2D
state = ovutils::OV_3D_VIDEO_ON_2D_PANEL;
}
} else {
// Content type is 2D
state = ovutils::OV_2D_VIDEO_ON_PANEL;
}
}
return state;
}
void setOverlayState(hwc_context_t *ctx, ovutils::eOverlayState state)
{
if (!ctx) {
ALOGE("%s: NULL ctx", __FUNCTION__);
return;
}
overlay::Overlay *ov = ctx->mOverlay;
if (!ov) {
ALOGE("%s: NULL OV object", __FUNCTION__);
return;
}
ov->setState(state);
}
bool prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
{
bool ret = false;
if (LIKELY(ctx->mOverlay)) {
private_handle_t *hnd = (private_handle_t *)layer->handle;
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
// Set overlay state
ovutils::eOverlayState state = determineOverlayState(ctx, 0, info.format);
setOverlayState(ctx, state);
ovutils::eDest dest = ovutils::OV_PIPE_ALL;
// In the true UI mirroring case, video needs to go to OV_PIPE0 (for
// primary) and OV_PIPE1 (for external)
if (state == ovutils::OV_2D_TRUE_UI_MIRROR) {
dest = static_cast<ovutils::eDest>(
ovutils::OV_PIPE0 | ovutils::OV_PIPE1);
}
// Order order order
// setSource - just setting source
// setParameter - changes src w/h/f accordingly
// setCrop - ROI - that is src_rect
// setPosition - need to do scaling
// commit - commit changes to mdp driver
// queueBuffer - not here, happens when draw is called
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
}
// FIXME: Use source orientation for TV when source is portrait
int transform = layer->transform & FINAL_TRANSFORM_MASK;
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(transform);
ovutils::eWait waitFlag = ovutils::NO_WAIT;
if (ctx->skipComposition == true) {
waitFlag = ovutils::WAIT;
}
ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
if (ctx->numHwLayers == 1) {
isFgFlag = ovutils::IS_FG_SET;
}
ovutils::PipeArgs parg(mdpFlags,
orient,
info,
waitFlag,
ovutils::ZORDER_0,
isFgFlag,
ovutils::ROT_FLAG_DISABLED);
ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
ret = ov.setSource(pargs, dest);
if (!ret) {
ALOGE("%s: setSource failed", __FUNCTION__);
return ret;
}
const ovutils::Params prms (ovutils::OVERLAY_TRANSFORM, orient);
ret = ov.setParameter(prms, dest);
if (!ret) {
ALOGE("%s: setParameter failed transform %x", __FUNCTION__, orient);
return ret;
}
hwc_rect_t sourceCrop = layer->sourceCrop;
// x,y,w,h
ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, // x, y
sourceCrop.right - sourceCrop.left, // w
sourceCrop.bottom - sourceCrop.top);// h
ret = ov.setCrop(dcrop, dest);
if (!ret) {
ALOGE("%s: setCrop failed", __FUNCTION__);
return ret;
}
int orientation = 0;
ovutils::Dim dim;
hwc_rect_t displayFrame = layer->displayFrame;
dim.x = displayFrame.left;
dim.y = displayFrame.top;
dim.w = (displayFrame.right - displayFrame.left);
dim.h = (displayFrame.bottom - displayFrame.top);
dim.o = orientation;
ret = ov.setPosition(dim, dest);
if (!ret) {
ALOGE("%s: setPosition failed", __FUNCTION__);
return ret;
}
if (!ov.commit(dest)) {
ALOGE("%s: commit fails", __FUNCTION__);
return false;
}
}
return true;
}
bool drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer)
{
private_handle_t *hnd = (private_handle_t *)layer->handle;
// Lock this buffer for read.
ctx->qbuf->lockAndAdd(hnd);
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eOverlayState state = ov.getState();
// Differentiate between states that need to wait for vsync
switch (state) {
case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
case ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
case ovutils::OV_2D_TRUE_UI_MIRROR:
// If displaying on both primary and external, must play each
// pipe individually since wait for vsync needs to be done at
// the end. Do the following:
// - Play external
// - Play primary
// - Wait for external vsync to be done
// NOTE: In these states
// - primary VG = OV_PIPE0
// - external VG = OV_PIPE1
// - external RGB = OV_PIPE2
// - Only in true UI mirroring case, played by fb
// Same FD for both primary and external VG pipes
ov.setMemoryId(hnd->fd, static_cast<ovutils::eDest>(
ovutils::OV_PIPE0 | ovutils::OV_PIPE1));
// Play external
if (!ov.queueBuffer(hnd->offset, ovutils::OV_PIPE1)) {
ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
ret = false;
}
// Play primary
if (!ov.queueBuffer(hnd->offset, ovutils::OV_PIPE0)) {
ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
ret = false;
}
// Wait for external vsync to be done
if (!ov.waitForVsync(ovutils::OV_PIPE1)) {
ALOGE("%s: waitForVsync failed for external", __FUNCTION__);
ret = false;
}
break;
default:
// In most cases, displaying only to one (primary or external)
// so use OV_PIPE_ALL since overlay will ignore NullPipes
ov.setMemoryId(hnd->fd, ovutils::OV_PIPE_ALL);
if (!ov.queueBuffer(hnd->offset, ovutils::OV_PIPE_ALL)) {
ALOGE("%s: queueBuffer failed", __FUNCTION__);
ret = false;
}
break;
}
if (!ret) {
ALOGE("%s: failed", __FUNCTION__);
}
return ret;
}
void cleanOverlays(hwc_context_t *ctx )
{
//XXX: handle for HDMI
if(0 == ctx->yuvBufferCount)
setOverlayState(ctx, ovutils::OV_CLOSED);
}
}; //namespace qhwc

View File

@@ -17,6 +17,7 @@
#include "hwc_utils.h" #include "hwc_utils.h"
#include "mdp_version.h" #include "mdp_version.h"
#include "hwc_video.h"
namespace qhwc { namespace qhwc {
void initContext(hwc_context_t *ctx) void initContext(hwc_context_t *ctx)
@@ -37,6 +38,7 @@ void closeContext(hwc_context_t *ctx)
delete ctx->mOverlay; delete ctx->mOverlay;
ctx->mOverlay = NULL; ctx->mOverlay = NULL;
} }
if(ctx->fbDev) { if(ctx->fbDev) {
framebuffer_close(ctx->fbDev); framebuffer_close(ctx->fbDev);
ctx->fbDev = NULL; ctx->fbDev = NULL;
@@ -73,28 +75,90 @@ void dumpLayer(hwc_layer_t const* l)
void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list) void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
{ {
int yuvBufCount = 0; //Video specific stats
int layersNotUpdatingCount = 0; int yuvCount = 0;
for (size_t i=0 ; i<list->numHwLayers; i++) { int yuvLayerIndex = -1;
private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle; bool isYuvLayerSkip = false;
for (size_t i = 0; i < list->numHwLayers; i++) {
private_handle_t *hnd =
(private_handle_t *)list->hwLayers[i].handle;
if (isYuvBuffer(hnd)) { if (isYuvBuffer(hnd)) {
yuvBufCount++; yuvCount++;
yuvLayerIndex = i;
//Animating
if (isSkipLayer(&list->hwLayers[i])) {
isYuvLayerSkip = true;
}
} else if (isSkipLayer(&list->hwLayers[i])) { //Popups
//If video layer is below a skip layer
if(yuvLayerIndex != -1 && yuvLayerIndex < (ssize_t)i) {
isYuvLayerSkip = true;
} }
} }
// Number of video/camera layers drawable with overlay }
ctx->yuvBufferCount = yuvBufCount;
VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);
ctx->numHwLayers = list->numHwLayers; ctx->numHwLayers = list->numHwLayers;
return; return;
} }
void handleYUV(hwc_context_t *ctx, hwc_layer_t *layer) //Crops source buffer against destination and FB boundaries
{ void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
private_handle_t *hnd = const int fbWidth, const int fbHeight) {
(private_handle_t *)layer->handle;
//XXX: Handle targets not using overlay int& crop_x = crop.left;
if(prepareOverlay(ctx, layer)) { int& crop_y = crop.top;
layer->compositionType = HWC_OVERLAY; int& crop_r = crop.right;
layer->hints |= HWC_HINT_CLEAR_FB; int& crop_b = crop.bottom;
int crop_w = crop.right - crop.left;
int crop_h = crop.bottom - crop.top;
int& dst_x = dst.left;
int& dst_y = dst.top;
int& dst_r = dst.right;
int& dst_b = dst.bottom;
int dst_w = dst.right - dst.left;
int dst_h = dst.bottom - dst.top;
if(dst_x < 0) {
float scale_x = crop_w * 1.0f / dst_w;
float diff_factor = (scale_x * abs(dst_x));
crop_x = crop_x + (int)diff_factor;
crop_w = crop_r - crop_x;
dst_x = 0;
dst_w = dst_r - dst_x;;
}
if(dst_r > fbWidth) {
float scale_x = crop_w * 1.0f / dst_w;
float diff_factor = scale_x * (dst_r - fbWidth);
crop_r = crop_r - diff_factor;
crop_w = crop_r - crop_x;
dst_r = fbWidth;
dst_w = dst_r - dst_x;
}
if(dst_y < 0) {
float scale_y = crop_h * 1.0f / dst_h;
float diff_factor = scale_y * abs(dst_y);
crop_y = crop_y + diff_factor;
crop_h = crop_b - crop_y;
dst_y = 0;
dst_h = dst_b - dst_y;
}
if(dst_b > fbHeight) {
float scale_y = crop_h * 1.0f / dst_h;
float diff_factor = scale_y * (dst_b - fbHeight);
crop_b = crop_b - diff_factor;
crop_h = crop_b - crop_y;
dst_b = fbHeight;
dst_h = dst_b - dst_y;
} }
} }
};//namespace };//namespace

View File

@@ -47,10 +47,12 @@ enum external_display_type {
// Utility functions - implemented in hwc_utils.cpp // Utility functions - implemented in hwc_utils.cpp
void dumpLayer(hwc_layer_t const* l); void dumpLayer(hwc_layer_t const* l);
void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list); void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list);
void handleYUV(hwc_context_t *ctx, hwc_layer_t *layer);
void initContext(hwc_context_t *ctx); void initContext(hwc_context_t *ctx);
void closeContext(hwc_context_t *ctx); void closeContext(hwc_context_t *ctx);
void openFramebufferDevice(hwc_context_t *ctx); void openFramebufferDevice(hwc_context_t *ctx);
//Crops source buffer against destination and FB boundaries
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
const int fbWidth, const int fbHeight);
// Inline utility functions // Inline utility functions
static inline bool isSkipLayer(const hwc_layer_t* l) { static inline bool isSkipLayer(const hwc_layer_t* l) {
@@ -67,27 +69,7 @@ static inline bool isBufferLocked(const private_handle_t* hnd) {
return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags)); return (hnd && (private_handle_t::PRIV_FLAGS_HWC_LOCK & hnd->flags));
} }
// ----------------------------------------------------------------------------- }; //qhwc namespace
// Overlay specific functions - inline or implemented in hwc_overlay.cpp
bool prepareOverlay(hwc_context_t *ctx, hwc_layer_t *layer);
//XXX: Refine draw functions
bool drawLayerUsingOverlay(hwc_context_t *ctx, hwc_layer_t *layer);
//XXX: Refine
void cleanOverlays(hwc_context_t *ctx );
void setOverlayState(hwc_context_t* ctx, ovutils::eOverlayState state);
// -----------------------------------------------------------------------------
// Copybit specific functions - inline or implemented in hwc_copybit.cpp
// -----------------------------------------------------------------------------
// HDMI specific functions - inline or implemented in hwc_hdmi.cpp
} //qhwc namespace
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -95,13 +77,11 @@ void setOverlayState(hwc_context_t* ctx, ovutils::eOverlayState state);
// This structure contains overall state // This structure contains overall state
struct hwc_context_t { struct hwc_context_t {
hwc_composer_device_t device; hwc_composer_device_t device;
// Layer variables
int yuvBufferCount;
int hdmiEnabled; int hdmiEnabled;
int numHwLayers; int numHwLayers;
int mdpVersion; int mdpVersion;
bool hasOverlay; bool hasOverlay;
bool skipComposition; int overlayInUse;
//Framebuffer device //Framebuffer device
framebuffer_device_t *fbDev; framebuffer_device_t *fbDev;
@@ -113,7 +93,4 @@ struct hwc_context_t {
qhwc::QueuedBufferStore *qbuf; qhwc::QueuedBufferStore *qbuf;
}; };
#endif //HWC_UTILS_H #endif //HWC_UTILS_H

238
libhwcomposer/hwc_video.cpp Normal file
View File

@@ -0,0 +1,238 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hwc_video.h"
namespace qhwc {
#define FINAL_TRANSFORM_MASK 0x000F
#define VIDEO_DEBUG 0
//Static Members
ovutils::eOverlayState VideoOverlay::sState = ovutils::OV_CLOSED;
int VideoOverlay::sYuvCount = 0;
int VideoOverlay::sYuvLayerIndex = -1;
bool VideoOverlay::sIsModeOn = false;
bool VideoOverlay::sIsLayerSkip = false;
//Cache stats, figure out the state, config overlay
bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) {
sIsModeOn = false;
chooseState(ctx);
//if the state chosen above is CLOSED, skip this block.
if(sState != ovutils::OV_CLOSED) {
if(configure(ctx, &list->hwLayers[sYuvLayerIndex])) {
markFlags(&list->hwLayers[sYuvLayerIndex]);
}
}
ALOGD_IF(VIDEO_DEBUG, "%s: stats: yuvCount = %d, yuvIndex = %d,"
"IsModeOn = %d, IsSkipLayer = %d", __FUNCTION__, sYuvCount,
sYuvLayerIndex, sIsModeOn, sIsLayerSkip);
return sIsModeOn;
}
void VideoOverlay::chooseState(hwc_context_t *ctx) {
ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__,
ovutils::getStateString(sState));
ovutils::eOverlayState newState = ovutils::OV_CLOSED;
//TODO check if device supports overlay and hdmi
//Support 1 video layer
if(sYuvCount == 1) {
if(sIsLayerSkip && ctx->hdmiEnabled) { //Skip on primary, display on ext.
//TODO
//VIDEO_ON_TV_ONLY
} else if(sIsLayerSkip) { //skip on primary, no ext
newState = ovutils::OV_CLOSED;
} else if(ctx->hdmiEnabled) { //display on both
newState = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
} else { //display on primary only
newState = ovutils::OV_2D_VIDEO_ON_PANEL;
}
}
sState = newState;
ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
ovutils::getStateString(sState));
}
void VideoOverlay::markFlags(hwc_layer_t *layer) {
switch(sState) {
case ovutils::OV_2D_VIDEO_ON_PANEL:
case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
layer->compositionType = HWC_OVERLAY;
layer->hints |= HWC_HINT_CLEAR_FB;
break;
//TODO
//case ovutils::OV_2D_VIDEO_ON_TV:
//just break, dont update flags.
default:
break;
}
}
bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_t *layer)
{
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
// Set overlay state
ov.setState(sState);
private_handle_t *hnd = (private_handle_t *)layer->handle;
ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
//TODO change this based on state.
ovutils::eDest dest = ovutils::OV_PIPE_ALL;
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
}
ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
if (ctx->numHwLayers == 1) {
isFgFlag = ovutils::IS_FG_SET;
}
ovutils::PipeArgs parg(mdpFlags,
info,
ovutils::ZORDER_0,
isFgFlag,
ovutils::ROT_FLAG_DISABLED);
ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
ov.setSource(pargs, dest);
hwc_rect_t sourceCrop = layer->sourceCrop;
// x,y,w,h
ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
sourceCrop.right - sourceCrop.left,
sourceCrop.bottom - sourceCrop.top);
//Only for External
ov.setCrop(dcrop, ovutils::OV_PIPE1);
// FIXME: Use source orientation for TV when source is portrait
//Only for External
ov.setTransform(0, dest);
ovutils::Dim dpos;
hwc_rect_t displayFrame = layer->displayFrame;
dpos.x = displayFrame.left;
dpos.y = displayFrame.top;
dpos.w = (displayFrame.right - displayFrame.left);
dpos.h = (displayFrame.bottom - displayFrame.top);
//Only for External
ov.setPosition(dpos, ovutils::OV_PIPE1);
//Calculate the rect for primary based on whether the supplied position
//is within or outside bounds.
const int fbWidth =
ovutils::FrameBufferInfo::getInstance()->getWidth();
const int fbHeight =
ovutils::FrameBufferInfo::getInstance()->getHeight();
if( displayFrame.left < 0 ||
displayFrame.top < 0 ||
displayFrame.right > fbWidth ||
displayFrame.bottom > fbHeight) {
calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight);
//Update calculated width and height
dcrop.w = sourceCrop.right - sourceCrop.left;
dcrop.h = sourceCrop.bottom - sourceCrop.top;
dpos.w = displayFrame.right - displayFrame.left;
dpos.h = displayFrame.bottom - displayFrame.top;
}
//Only for Primary
ov.setCrop(dcrop, ovutils::OV_PIPE0);
int transform = layer->transform & FINAL_TRANSFORM_MASK;
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(transform);
ov.setTransform(orient, ovutils::OV_PIPE0);
ov.setPosition(dpos, ovutils::OV_PIPE0);
//Both prim and external
if (!ov.commit(dest)) {
ALOGE("%s: commit fails", __FUNCTION__);
return false;
}
sIsModeOn = true;
}
return sIsModeOn;
}
bool VideoOverlay::draw(hwc_context_t *ctx, hwc_layer_list_t *list)
{
if(!sIsModeOn || sYuvLayerIndex == -1) {
return true;
}
private_handle_t *hnd =
(private_handle_t *)list->hwLayers[sYuvLayerIndex].handle;
// Lock this buffer for read.
ctx->qbuf->lockAndAdd(hnd);
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eOverlayState state = ov.getState();
switch (state) {
case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
case ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
// Play external
if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
ret = false;
}
// Play primary
if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) {
ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
ret = false;
}
// Wait for external vsync to be done
if (!ov.waitForVsync(ovutils::OV_PIPE1)) {
ALOGE("%s: waitForVsync failed for external", __FUNCTION__);
ret = false;
}
break;
default:
// In most cases, displaying only to one (primary or external)
// so use OV_PIPE_ALL since overlay will ignore NullPipes
if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE_ALL)) {
ALOGE("%s: queueBuffer failed", __FUNCTION__);
ret = false;
}
break;
}
return ret;
}
}; //namespace qhwc

67
libhwcomposer/hwc_video.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HWC_VIDEO_H
#define HWC_VIDEO_H
#include "hwc_utils.h"
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
namespace qhwc {
//Feature for using overlay to display videos.
class VideoOverlay {
public:
//Sets up members and prepares overlay if conditions are met
static bool prepare(hwc_context_t *ctx, hwc_layer_list_t *list);
//Draws layer if this feature is on
static bool draw(hwc_context_t *ctx, hwc_layer_list_t *list);
//Receives data from hwc
static void setStats(int yuvCount, int yuvLayerIndex, bool isYuvLayerSkip);
private:
//Choose an appropriate overlay state based on conditions
static void chooseState(hwc_context_t *ctx);
//Configures overlay
static bool configure(hwc_context_t *ctx, hwc_layer_t *layer);
//Marks layer flags if this feature is used
static void markFlags(hwc_layer_t *layer);
//returns yuv count
static int getYuvCount();
//The chosen overlay state.
static ovutils::eOverlayState sState;
//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 if this feature is on.
static bool sIsModeOn;
};
inline void VideoOverlay::setStats(int yuvCount, int yuvLayerIndex,
bool isYuvLayerSkip) {
sYuvCount = yuvCount;
sYuvLayerIndex = yuvLayerIndex;
sIsLayerSkip = isYuvLayerSkip;
}
inline int VideoOverlay::getYuvCount() { return sYuvCount; }
}; //namespace qhwc
#endif //HWC_VIDEO_H

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@@ -76,7 +76,7 @@ bool getOverlay(int fd, mdp_overlay& ov);
bool play(int fd, msmfb_overlay_data& od); bool play(int fd, msmfb_overlay_data& od);
/* MSMFB_OVERLAY_PLAY_WAIT */ /* MSMFB_OVERLAY_PLAY_WAIT */
bool playWait(int fd, msmfb_overlay_data& od); bool waitForVsync(int fd, msmfb_overlay_data& od);
/* MSMFB_OVERLAY_3D */ /* MSMFB_OVERLAY_3D */
bool set3D(int fd, msmfb_overlay_3d& ov); bool set3D(int fd, msmfb_overlay_3d& ov);
@@ -102,96 +102,108 @@ void dump(const char* const s, const fb_var_screeninfo& vinfo);
//---------------Inlines ------------------------------------- //---------------Inlines -------------------------------------
inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) { inline bool getFScreenInfo(int fd, fb_fix_screeninfo& finfo) {
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) { if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) < 0) {
ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%d", errno); ALOGE("Failed to call ioctl FBIOGET_FSCREENINFO err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) { inline bool getVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%d", errno); ALOGE("Failed to call ioctl FBIOGET_VSCREENINFO err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) { inline bool setVScreenInfo(int fd, fb_var_screeninfo& vinfo) {
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) == -1) { if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) < 0) {
ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%d", errno); ALOGE("Failed to call ioctl FBIOPUT_VSCREENINFO err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool startRotator(int fd, msm_rotator_img_info& rot) { inline bool startRotator(int fd, msm_rotator_img_info& rot) {
if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) == -1){ if (ioctl(fd, MSM_ROTATOR_IOCTL_START, &rot) < 0){
ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%d", errno); ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_START err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool rotate(int fd, msm_rotator_data_info& rot) { inline bool rotate(int fd, msm_rotator_data_info& rot) {
if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) == -1) { if (ioctl(fd, MSM_ROTATOR_IOCTL_ROTATE, &rot) < 0) {
ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%d", errno); ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_ROTATE err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool setOverlay(int fd, mdp_overlay& ov) { inline bool setOverlay(int fd, mdp_overlay& ov) {
if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) == -1) { if (ioctl(fd, MSMFB_OVERLAY_SET, &ov) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%d", errno); ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool endRotator(int fd, int sessionId) { inline bool endRotator(int fd, int sessionId) {
if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) == -1) { if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) {
ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%d", errno); ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool unsetOverlay(int fd, int ovId) { inline bool unsetOverlay(int fd, int ovId) {
if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) == -1) { if (ioctl(fd, MSMFB_OVERLAY_UNSET, &ovId) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%d", errno); ALOGE("Failed to call ioctl MSMFB_OVERLAY_UNSET err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool getOverlay(int fd, mdp_overlay& ov) { inline bool getOverlay(int fd, mdp_overlay& ov) {
if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) == -1) { if (ioctl(fd, MSMFB_OVERLAY_GET, &ov) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%d", errno); ALOGE("Failed to call ioctl MSMFB_OVERLAY_GET err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool play(int fd, msmfb_overlay_data& od) { inline bool play(int fd, msmfb_overlay_data& od) {
if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) == -1) { if (ioctl(fd, MSMFB_OVERLAY_PLAY, &od) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%d", errno); ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool playWait(int fd, msmfb_overlay_data& od) { inline bool waitForVsync(int fd, msmfb_overlay_data& od) {
if (ioctl(fd, MSMFB_OVERLAY_PLAY_WAIT, &od) == -1) { if (ioctl(fd, MSMFB_OVERLAY_PLAY_WAIT, &od) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY_WAIT err=%d", errno); ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY_WAIT err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
} }
inline bool set3D(int fd, msmfb_overlay_3d& ov) { inline bool set3D(int fd, msmfb_overlay_3d& ov) {
if (ioctl(fd, MSMFB_OVERLAY_3D, &ov) == -1) { if (ioctl(fd, MSMFB_OVERLAY_3D, &ov) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_3D err=%d", errno); ALOGE("Failed to call ioctl MSMFB_OVERLAY_3D err=%s",
strerror(errno));
return false; return false;
} }
return true; return true;
@@ -262,7 +274,6 @@ inline void dump(const char* const s, const fb_var_screeninfo& vinfo) {
s, vinfo.xres, vinfo.yres); s, vinfo.xres, vinfo.yres);
} }
} // mdp_wrapper } // mdp_wrapper
} // overlay } // overlay

View File

@@ -31,10 +31,8 @@
#include "overlayImpl.h" #include "overlayImpl.h"
#include "overlay.h" #include "overlay.h"
// MDP related FIXME move to state
#include "overlayMdp.h" #include "overlayMdp.h"
#include "overlayCtrlData.h" #include "overlayCtrlData.h"
#include "overlayRotator.h"
namespace overlay { namespace overlay {
@@ -42,56 +40,9 @@ Overlay::Overlay(): mOv(0) {
} }
Overlay::~Overlay() { Overlay::~Overlay() {
if(mState.state() == utils::OV_CLOSED) return;
close();
delete mOv;
mOv = 0;
}
bool Overlay::open() {
// We need an empty open to just open the bare minimum for business
return true;
}
void Overlay::reset(){
if(mOv && !mOv->close()) {
ALOGE("%s Overlay failed", __FUNCTION__);
}
delete mOv;
mOv = 0;
}
bool Overlay::close()
{
OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point",
__FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state();
switch (st) {
case utils::OV_CLOSED:
// try to close any partially opened items
break;
case utils::OV_2D_VIDEO_ON_PANEL:
case utils::OV_2D_VIDEO_ON_PANEL_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
case utils::OV_UI_MIRROR:
case utils::OV_2D_TRUE_UI_MIRROR:
case utils::OV_BYPASS_1_LAYER:
case utils::OV_BYPASS_2_LAYER:
case utils::OV_BYPASS_3_LAYER:
mOv = mState.handleEvent(utils::OV_CLOSED, mOv); mOv = mState.handleEvent(utils::OV_CLOSED, mOv);
this->reset(); delete mOv;
break; mOv = 0;
default:
OVASSERT(false, "close Unknown state %d", st);
return false;
}
return true;
} }
bool Overlay::commit(utils::eDest dest) bool Overlay::commit(utils::eDest dest)
@@ -99,7 +50,6 @@ bool Overlay::commit(utils::eDest dest)
OVASSERT(mOv, OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point", "%s Overlay and Rotator should be init at this point",
__FUNCTION__); __FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
@@ -125,13 +75,12 @@ bool Overlay::commit(utils::eDest dest)
return true; return true;
} }
bool Overlay::queueBuffer(uint32_t offset, bool Overlay::queueBuffer(int fd, uint32_t offset,
utils::eDest dest) utils::eDest dest)
{ {
OVASSERT(mOv, OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point", "%s Overlay and Rotator should be init at this point",
__FUNCTION__); __FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
@@ -145,39 +94,7 @@ bool Overlay::queueBuffer(uint32_t offset,
case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_1_LAYER:
case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_2_LAYER:
case utils::OV_BYPASS_3_LAYER: case utils::OV_BYPASS_3_LAYER:
if(!mOv->queueBuffer(offset, dest)) { if(!mOv->queueBuffer(fd, offset, dest)) {
ALOGE("Overlay %s failed", __FUNCTION__);
return false;
}
break;
default:
OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
return false;
}
return true;
}
bool Overlay::dequeueBuffer(void*& buf,
utils::eDest dest)
{
OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point",
__FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state();
switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL:
case utils::OV_2D_VIDEO_ON_PANEL_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
case utils::OV_UI_MIRROR:
case utils::OV_2D_TRUE_UI_MIRROR:
case utils::OV_BYPASS_1_LAYER:
case utils::OV_BYPASS_2_LAYER:
case utils::OV_BYPASS_3_LAYER:
if(!mOv->dequeueBuffer(buf, dest)) {
ALOGE("Overlay %s failed", __FUNCTION__); ALOGE("Overlay %s failed", __FUNCTION__);
return false; return false;
} }
@@ -194,7 +111,6 @@ bool Overlay::waitForVsync(utils::eDest dest)
OVASSERT(mOv, OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point", "%s Overlay and Rotator should be init at this point",
__FUNCTION__); __FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
@@ -226,7 +142,6 @@ bool Overlay::setCrop(const utils::Dim& d,
OVASSERT(mOv, OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point", "%s Overlay and Rotator should be init at this point",
__FUNCTION__); __FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
@@ -257,7 +172,6 @@ bool Overlay::setPosition(const utils::Dim& d,
OVASSERT(mOv, OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point", "%s Overlay and Rotator should be init at this point",
__FUNCTION__); __FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
@@ -282,13 +196,13 @@ bool Overlay::setPosition(const utils::Dim& d,
} }
return true; return true;
} }
bool Overlay::setParameter(const utils::Params& param,
bool Overlay::setTransform(const int orient,
utils::eDest dest) utils::eDest dest)
{ {
OVASSERT(mOv, utils::eTransform transform =
"%s Overlay and Rotator should be init at this point", static_cast<utils::eTransform>(orient);
__FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
@@ -302,7 +216,7 @@ bool Overlay::setParameter(const utils::Params& param,
case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_1_LAYER:
case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_2_LAYER:
case utils::OV_BYPASS_3_LAYER: case utils::OV_BYPASS_3_LAYER:
if(!mOv->setParameter(param, dest)) { if(!mOv->setTransform(transform, dest)) {
ALOGE("Overlay %s failed", __FUNCTION__); ALOGE("Overlay %s failed", __FUNCTION__);
return false; return false;
} }
@@ -313,25 +227,19 @@ bool Overlay::setParameter(const utils::Params& param,
} }
return true; return true;
} }
bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES], bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES],
utils::eDest dest) utils::eDest dest)
{ {
// FIXME that one needs to move to the state machine class
utils::PipeArgs margs[utils::MAX_PIPES] = { utils::PipeArgs margs[utils::MAX_PIPES] = {
args[0], args[1], args[2] }; args[0], args[1], args[2] };
utils::eOverlayState st = mState.state(); utils::eOverlayState st = mState.state();
switch (st) { switch (st) {
case utils::OV_CLOSED: case utils::OV_CLOSED:
// if we get setSource when we are closed, then ALOGE("Overlay %s failed, state is OV_CLOSED, set state first",
// we will assume tranistion to OV_2D_VIDEO_ON_PANEL __FUNCTION__);
// returns overlay
mOv = mState.handle_closed(utils::OV_2D_VIDEO_ON_PANEL);
if (!mOv) {
ALOGE("Overlay %s failed", __FUNCTION__);
this->reset(); // cleanup
return false; return false;
}
break; break;
case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL:
case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_2D_PANEL:
@@ -339,25 +247,15 @@ bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES],
case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_1_LAYER:
case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_2_LAYER:
case utils::OV_BYPASS_3_LAYER: case utils::OV_BYPASS_3_LAYER:
// no tweaking
break; break;
case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_TV: case utils::OV_3D_VIDEO_ON_3D_TV:
margs[utils::CHANNEL_1].zorder = utils::ZORDER_1; //TODO set zorder for channel 1 as 1 in 3D pipe
break;
case utils::OV_2D_VIDEO_ON_PANEL_TV: case utils::OV_2D_VIDEO_ON_PANEL_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
// If displaying on both, external VG pipe set to be no wait
margs[utils::CHANNEL_1].wait = utils::NO_WAIT;
break; break;
case utils::OV_2D_TRUE_UI_MIRROR: case utils::OV_2D_TRUE_UI_MIRROR:
// Set zorder -- external VG pipe (video) gets 0, RGB pipe (UI) gets 1 // TODO Set zorder, external VG pipe (video) gets 0, RGB pipe (UI) gets 1
margs[utils::CHANNEL_1].zorder = utils::ZORDER_0;
margs[utils::CHANNEL_2].zorder = utils::ZORDER_1;
// External VG (video) and RGB (UI) pipe set to be no wait
margs[utils::CHANNEL_0].wait = utils::WAIT;
margs[utils::CHANNEL_1].wait = utils::NO_WAIT;
margs[utils::CHANNEL_2].wait = utils::NO_WAIT;
break; break;
default: default:
OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st); OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st);
@@ -371,39 +269,12 @@ bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES],
return true; return true;
} }
void Overlay::setMemoryId(int id, utils::eDest dest)
{
OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point",
__FUNCTION__);
// FIXME that one needs to move to the state machine class
utils::eOverlayState st = mState.state();
switch (st) {
case utils::OV_2D_VIDEO_ON_PANEL:
case utils::OV_2D_VIDEO_ON_PANEL_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_PANEL:
case utils::OV_3D_VIDEO_ON_3D_TV:
case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
case utils::OV_UI_MIRROR:
case utils::OV_2D_TRUE_UI_MIRROR:
case utils::OV_BYPASS_1_LAYER:
case utils::OV_BYPASS_2_LAYER:
case utils::OV_BYPASS_3_LAYER:
mOv->setMemoryId(id, dest);
break;
default:
OVASSERT(false, "setMemId Unknown state %d", st);
}
}
void Overlay::dump() const void Overlay::dump() const
{ {
OVASSERT(mOv, OVASSERT(mOv,
"%s Overlay and Rotator should be init at this point", "%s Overlay and Rotator should be init at this point",
__FUNCTION__); __FUNCTION__);
// FIXME dump tate object, factory
ALOGE("== Dump Overlay start =="); ALOGE("== Dump Overlay start ==");
mState.dump(); mState.dump();
mOv->dump(); mOv->dump();
@@ -426,30 +297,4 @@ Overlay* Overlay::getInstance() {
return sInstance; return sInstance;
} }
/**** NullPipe ****/
bool NullPipe::open(RotatorBase*) {
ALOGE_IF(DEBUG_OVERLAY, "NullPipe open");
return true;
}
bool NullPipe::close() { return true; }
bool NullPipe::commit() { return true; }
bool NullPipe::start(const utils::PipeArgs&) { return true; }
bool NullPipe::setCrop(const utils::Dim&) { return true; }
bool NullPipe::setPosition(const utils::Dim&) { return true; }
bool NullPipe::setParameter(const utils::Params&) { return true; }
bool NullPipe::setSource(const utils::PipeArgs&) { return true; }
bool NullPipe::queueBuffer(uint32_t offset) { return true; }
bool NullPipe::dequeueBuffer(void*&) { return true; }
bool NullPipe::waitForVsync() { return true; }
void NullPipe::setMemoryId(int) {}
// NullPipe will return by val here as opposed to other Pipes.
utils::PipeArgs NullPipe::getArgs() const { return utils::PipeArgs(); }
utils::eOverlayPipeType NullPipe::getOvPipeType() const {
return utils::OV_PIPE_TYPE_NULL;
}
void NullPipe::dump() const {
ALOGE("== NullPipe (null) start/end ==");
}
} // overlay } // overlay

View File

@@ -43,31 +43,22 @@ public:
/* Overlay related func */ /* Overlay related func */
/* We need an empty open to just open the bare minimum for
* business. */
bool open();
/* close rotator, state, overlayimpl*/
bool close();
/* Following is the same as the pure virt interface in ov impl */ /* Following is the same as the pure virt interface in ov impl */
bool commit(utils::eDest dest = utils::OV_PIPE_ALL); bool setSource(const utils::PipeArgs args[utils::MAX_PIPES],
bool queueBuffer(uint32_t offset,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
bool dequeueBuffer(void*& buf,
utils::eDest dest = utils::OV_PIPE_ALL);
bool waitForVsync(utils::eDest dest = utils::OV_PIPE1);
bool setCrop(const utils::Dim& d, bool setCrop(const utils::Dim& d,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
bool setTransform(const int orientation,
utils::eDest dest = utils::OV_PIPE_ALL);
bool setPosition(const utils::Dim& dim, bool setPosition(const utils::Dim& dim,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
bool setParameter(const utils::Params& param, bool commit(utils::eDest dest = utils::OV_PIPE_ALL);
bool queueBuffer(int fd, uint32_t offset,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
bool setSource(const utils::PipeArgs args[utils::MAX_PIPES], bool waitForVsync(utils::eDest dest = utils::OV_PIPE1);
utils::eDest dest = utils::OV_PIPE_ALL);
void setMemoryId(int id, utils::eDest dest = utils::OV_PIPE_ALL);
void dump() const; void dump() const;
/* state related functions */ /* state related functions */

View File

@@ -18,14 +18,14 @@
#include <cutils/properties.h> #include <cutils/properties.h>
#include "overlayCtrlData.h" #include "overlayCtrlData.h"
#include "fb_priv.h" #include "fb_priv.h"
#include "gralloc_priv.h" //for interlace
namespace overlay{ namespace overlay{
bool Ctrl::open(uint32_t fbnum, bool Ctrl::init(uint32_t fbnum) {
RotatorBase* rot) { // MDP/FD init
// MDP/FD open if(!mMdp.init(fbnum)) {
if(!mMdp.open(fbnum)) { ALOGE("Ctrl failed to init fbnum=%d", fbnum);
ALOGE("Ctrl failed to open fbnum=%d", fbnum);
return false; return false;
} }
@@ -34,127 +34,12 @@ bool Ctrl::open(uint32_t fbnum,
return false; return false;
} }
OVASSERT(rot, "rot is null");
mRot = rot;
// rot should be already opened
return true; return true;
} }
bool Ctrl::start(const utils::PipeArgs& args)
{
int colorFormat = utils::getColorFormat(args.whf.format);
utils::eMdpFlags flags = args.mdpFlags;
//XXX: Support for interlaced content
if (0) {
setMdpFlags(flags, utils::OV_MDP_DEINTERLACE);
// Get the actual format
colorFormat = args.whf.format ^ HAL_PIXEL_FORMAT_INTERLACE;
}
utils::Whf hwwhf(args.whf);
int fmt = utils::getMdpFormat(colorFormat);
// FIXME format should probably be int and not uint
if (fmt < 0) {
ALOGE("Ctrl failed getMdpFormat unsopported "
"colorFormat=%d format=%d flags=%d",
colorFormat, fmt, flags);
return false;
}
hwwhf.format = fmt;
// devices should be already opened
// (by calling open earlier in the flow)
const utils::PipeArgs newargs(flags, // mdp flags
args.orientation, // trans
hwwhf,
args.wait,
args.zorder,
args.isFg,
args.rotFlags);
if (!setInfo(newargs)) {
ALOGE("Ctrl failed to setInfo mdpflags=%d wait=%d zorder=%d",
newargs.mdpFlags, newargs.wait, newargs.zorder);
hwwhf.dump();
return false;
}
// FIXME, can we remove that and have it in
// setSource only when source changed?
if(!mRot->start(newargs)) {
ALOGE("Ctrl failed to start Rotation session");
return false;
}
// if geom is different, we need to prepare a new rot buffers.
// remap on demand when the current orientation is 90,180, etc.
// and the prev orientation was 0. It means we go from orient
if(!mRot->remap(utils::ROT_NUM_BUFS, newargs)) {
ALOGE("%s Error in remapping", __FUNCTION__);
}
if(!mMdp.set()) {
ALOGE("Ctrl start failed set overlay");
return false;
}
// cache the src to be the current mCrop vals
mCrop.w = hwwhf.w;
mCrop.h = hwwhf.h;
return true;
}
inline void Ctrl::updateSource(RotatorBase* r,
const utils::PipeArgs& args,
utils::ScreenInfo& info)
{
mMdp.updateSource(r, args, info);
}
bool Ctrl::setSource(const utils::PipeArgs& args) bool Ctrl::setSource(const utils::PipeArgs& args)
{ {
mMdp.setWait(args.wait); return mMdp.setSource(args);
utils::PipeArgs newargs(args);
utils::Whf whf(args.whf);
// check geom change
if(mOvBufInfo != whf) {
// whf.format is given as HAL, that is why it is
// needed to be MDP fmt.
whf.format = utils::getColorFormat(whf.format);
int fmt = utils::getMdpFormat(whf.format);
OVASSERT(-1 != fmt, "Ctrl setSource format is -1");
whf.format = fmt;
newargs.whf = whf;
updateSource(mRot, newargs, mInfo);
mMdp.setUserData(0);
if(!mRot->start(newargs)) {
ALOGE("%s failed start rot", __FUNCTION__);
return false;
}
// if geom is different, we need to prepare a new rot buffers.
// remap on demand when the current orientation is 90,180, etc.
// and the prev orientation was 0. It means we go from orient
if(!mRot->remap(utils::ROT_NUM_BUFS, newargs)) {
ALOGE("%s Error in remapping", __FUNCTION__);
}
}
// needed for setSource
mOrient = args.orientation;
// cache last whf from gralloc hnd
mOvBufInfo = args.whf;
// orign impl is returning false here
// because they will close the overlay and reopen it.
// New design would not do that.
return true;
} }
bool Ctrl::setPosition(const utils::Dim& dim) bool Ctrl::setPosition(const utils::Dim& dim)
@@ -172,28 +57,10 @@ bool Ctrl::setPosition(const utils::Dim& dim)
return true; return true;
} }
bool Ctrl::setParameter(const utils::Params& p) bool Ctrl::setTransform(const utils::eTransform& orient, const bool& rotUsed)
{ {
if (utils::OVERLAY_TRANSFORM == p.param && if(!mMdp.setTransform(orient, rotUsed)) {
p.value == mMdp.getUserData()) { ALOGE("Ctrl setTransform failed for Mdp");
// nothing to do here
return true;
}
utils::eTransform trns = static_cast<utils::eTransform>(p.value);
switch (p.param) {
case utils::OVERLAY_DITHER:
// nothing here today
ALOGE("Ctrl setParameter OVERLAY_DITHER not impl");
return true;
case utils::OVERLAY_TRANSFORM:
if(!mRot->overlayTransform(mMdp, trns)) {
ALOGE("Ctrl setParameter failed Rot overlayTransform");
return false;
}
break;
default:
ALOGE("Ctrl setParameter unknown param %d", p.param);
return false; return false;
} }
return true; return true;
@@ -201,12 +68,10 @@ bool Ctrl::setParameter(const utils::Params& p)
bool Ctrl::setCrop(const utils::Dim& d) bool Ctrl::setCrop(const utils::Dim& d)
{ {
// FIXME check channel validity
if(!mMdp.setCrop(d)) { if(!mMdp.setCrop(d)) {
ALOGE("Data setCrop failed in MDP setCrop"); ALOGE("Data setCrop failed in MDP setCrop");
return false; return false;
} }
mCrop = d;
return true; return true;
} }
@@ -224,11 +89,9 @@ utils::Dim Ctrl::getAspectRatio(const utils::Whf& whf) const
} }
if (inWhf.w * fbHeight > fbWidth * inWhf.h) { if (inWhf.w * fbHeight > fbWidth * inWhf.h) {
inWhf.h = fbWidth * inWhf.h / inWhf.w; inWhf.h = fbWidth * inWhf.h / inWhf.w;
utils::even_out(inWhf.h);
inWhf.w = fbWidth; inWhf.w = fbWidth;
} else if (inWhf.w * fbHeight < fbWidth * inWhf.h) { } else if (inWhf.w * fbHeight < fbWidth * inWhf.h) {
inWhf.w = fbHeight * inWhf.w / inWhf.h; inWhf.w = fbHeight * inWhf.w / inWhf.h;
utils::even_out(inWhf.w);
inWhf.h = fbHeight; inWhf.h = fbHeight;
} else { } else {
inWhf.w = fbWidth; inWhf.w = fbWidth;
@@ -339,10 +202,8 @@ utils::Dim Ctrl::getAspectRatio(const utils::Dim& dim) const {
void Ctrl::dump() const { void Ctrl::dump() const {
ALOGE("== Dump Ctrl start =="); ALOGE("== Dump Ctrl start ==");
ALOGE("orient=%d", mOrient);
mInfo.dump("mInfo"); mInfo.dump("mInfo");
mMdp.dump(); mMdp.dump();
mRot->dump();
ALOGE("== Dump Ctrl end =="); ALOGE("== Dump Ctrl end ==");
} }

View File

@@ -38,65 +38,40 @@ namespace ovutils = overlay::utils;
namespace overlay { namespace overlay {
// FIXME make int to be uint32 whenever possible
class RotatorBase;
/* /*
* FIXME do we want rot to be template parameter?
* It's already using inheritance...
*
* Sequence to use: * Sequence to use:
* open * init
* start * start
* setXXX * setXXX
* close * close
*
* Can call setRot anytime to replace rotator on-the-fly
* */ * */
class Ctrl : utils::NoCopy { class Ctrl : utils::NoCopy {
public: public:
/* ctor */ /* ctor */
explicit Ctrl(); explicit Ctrl();
/* dtor close */ /* dtor close */
~Ctrl(); ~Ctrl();
/* init fd etc*/
/* should open devices? or start()? */ bool init(uint32_t fbnum);
bool open(uint32_t fbnum, RotatorBase* rot);
/* close underlying mdp */ /* close underlying mdp */
bool close(); bool close();
/* Invoke methods for opening underlying devices
* flags - PIPE SHARED
* wait - WAIT, NO_WAIT */
bool start(const utils::PipeArgs& args);
/* Dynamically set rotator*/
void setRot(RotatorBase* rot);
/* set mdp posision using dim */
bool setPosition(const utils::Dim& dim);
/* set param using Params (param,value pair) */
bool setParameter(const utils::Params& p);
/* set source using whf, orient and wait flag */ /* set source using whf, orient and wait flag */
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
/* set crop info and pass it down to mdp */ /* set crop info and pass it down to mdp */
bool setCrop(const utils::Dim& d); bool setCrop(const utils::Dim& d);
/* set orientation */
bool setTransform(const utils::eTransform& p, const bool&);
/* set mdp position using dim */
bool setPosition(const utils::Dim& dim);
/* mdp set overlay/commit changes */ /* mdp set overlay/commit changes */
bool commit(); bool commit();
/* ctrl id */ /* ctrl id */
int getId() const; int getPipeId() const;
/* ctrl fd */ /* ctrl fd */
int getFd() const; int getFd() const;
bool getRotSessId(int& id) const;
utils::Dim getAspectRatio(const utils::Whf& whf) const; utils::Dim getAspectRatio(const utils::Whf& whf) const;
utils::Dim getAspectRatio(const utils::Dim& dim) const; utils::Dim getAspectRatio(const utils::Dim& dim) const;
@@ -113,40 +88,14 @@ private:
/* Retrieve screen info from underlying mdp */ /* Retrieve screen info from underlying mdp */
bool getScreenInfo(utils::ScreenInfo& info); bool getScreenInfo(utils::ScreenInfo& info);
/* calls underlying mdp set info */
bool setInfo(const utils::PipeArgs& args);
/* given whf, update src */
void updateSource(RotatorBase* r,
const utils::PipeArgs& args,
utils::ScreenInfo& info);
// mdp ctrl struct(info e.g.) // mdp ctrl struct(info e.g.)
MdpCtrl mMdp; MdpCtrl mMdp;
// Rotator
RotatorBase* mRot;
/* Cache cropped value */
utils::Dim mCrop;
/* Screen info */ /* Screen info */
utils::ScreenInfo mInfo; utils::ScreenInfo mInfo;
/* orientation cache FIXME */
utils::eTransform mOrient;
/* Cache last known whfz.
* That would help us compare to a previous
* source that was submitted */
utils::Whf mOvBufInfo;
}; };
/*
* MDP = DataMdp, ROT = CtrlMdp usually since Rotator<>
* is instansiated with Ctrl data structure.
* */
class Data : utils::NoCopy { class Data : utils::NoCopy {
public: public:
/* init, reset */ /* init, reset */
@@ -155,44 +104,30 @@ public:
/* calls close */ /* calls close */
~Data(); ~Data();
/* should open devices? or start()? */ /* init fd etc */
bool open(uint32_t fbnum, RotatorBase* rot); bool init(uint32_t fbnum);
/* calls underlying mdp close */ /* calls underlying mdp close */
bool close(); bool close();
/* set the rotator */ /* set overlay pipe id in the mdp struct */
void setRot(RotatorBase* rot); void setPipeId(int id);
/* set memory id in the mdp struct */
void setMemoryId(int id);
/* set overlay id in the mdp struct */
void setId(int id);
/* get overlay id in the mdp struct */ /* get overlay id in the mdp struct */
int getId() const; int getPipeId() const;
/* queue buffer to the overlay */ /* queue buffer to the overlay */
bool queueBuffer(uint32_t offset); bool queueBuffer(int fd, uint32_t offset);
/* wait for vsync to be done */ /* wait for vsync to be done */
bool waitForVsync(); bool waitForVsync();
/* sump the state of the obj */ /* sump the state of the obj */
void dump() const; void dump() const;
private: private:
/* play wrapper */
bool play();
/* playWait wrapper */
bool playWait();
// mdp data struct // mdp data struct
MdpData mMdp; MdpData mMdp;
// Rotator
RotatorBase* mRot;
}; };
/* This class just creates a Ctrl Data pair to be used by a pipe. /* This class just creates a Ctrl Data pair to be used by a pipe.
@@ -207,7 +142,7 @@ struct CtrlData {
//-------------Inlines------------------------------- //-------------Inlines-------------------------------
inline Ctrl::Ctrl() : mRot(0), mOrient(utils::OVERLAY_TRANSFORM_0) { inline Ctrl::Ctrl() {
mMdp.reset(); mMdp.reset();
} }
@@ -216,7 +151,6 @@ inline Ctrl::~Ctrl() {
} }
inline bool Ctrl::close() { inline bool Ctrl::close() {
// do not close the rotator
if(!mMdp.close()) if(!mMdp.close())
return false; return false;
return true; return true;
@@ -238,70 +172,37 @@ inline bool Ctrl::getScreenInfo(utils::ScreenInfo& info) {
return true; return true;
} }
inline bool Ctrl::setInfo(const utils::PipeArgs& args) inline int Ctrl::getPipeId() const {
{ return mMdp.getPipeId();
// FIXME set flags, zorder and wait separtly
if(!mMdp.setInfo(mRot, args, mInfo)){
ALOGE("Ctrl failed to setInfo wait=%d mdpflags=%d "
"zorder=%d", args.wait, args.mdpFlags, args.zorder);
return false;
}
return true;
}
inline int Ctrl::getId() const {
// FIXME check channel up?
return mMdp.getId();
} }
inline int Ctrl::getFd() const { inline int Ctrl::getFd() const {
// FIXME check channel up?
return mMdp.getFd(); return mMdp.getFd();
} }
inline bool Ctrl::getRotSessId(int& id) const {
// FIXME check channel up?
// should be -1 in case of no rot session active
id = mRot->getSessId();
return true;
}
inline utils::ScreenInfo Ctrl::getScreenInfo() const { inline utils::ScreenInfo Ctrl::getScreenInfo() const {
return mInfo; return mInfo;
} }
inline utils::Dim Ctrl::getCrop() const { inline utils::Dim Ctrl::getCrop() const {
return mCrop; return mMdp.getSrcRectDim();
} }
inline Data::Data() {
inline Data::Data() : mRot(0) {
mMdp.reset(); mMdp.reset();
} }
inline Data::~Data() { close(); } inline Data::~Data() { close(); }
inline void Data::setRot(RotatorBase* rot) { mRot = rot; } inline void Data::setPipeId(int id) { mMdp.setPipeId(id); }
inline void Data::setMemoryId(int id) { mMdp.setMemoryId(id); } inline int Data::getPipeId() const { return mMdp.getPipeId(); }
// really a reqid inline bool Data::init(uint32_t fbnum) {
inline void Data::setId(int id) { mMdp.setId(id); } if(!mMdp.init(fbnum)) {
ALOGE("Data cannot init mdp");
inline int Data::getId() const { return mMdp.getId(); }
inline bool Data::open(uint32_t fbnum,
RotatorBase* rot) {
if(!mMdp.open(fbnum)) {
ALOGE("Data cannot open mdp");
return false; return false;
} }
OVASSERT(rot, "rot is null");
mRot = rot;
// rotator should be already opened here
return true; return true;
} }
@@ -313,49 +214,22 @@ inline bool Data::close() {
return true; return true;
} }
inline bool Data::queueBuffer(uint32_t offset) { inline bool Data::queueBuffer(int fd, uint32_t offset) {
// FIXME asserts on state validity return mMdp.play(fd, offset);
mMdp.setOffset(offset);
mRot->setRotDataSrcMemId(mMdp.getMemoryId());
// will play if succeeded
if(!mRot->prepareQueueBuf(offset)) {
ALOGE("Data failed to prepareQueueBuf");
return false;
}
// Play can go either from mdp or rot
if(!this->play()){
ALOGE("Data error in MDP/ROT play");
return false;
}
return true;
} }
inline bool Data::waitForVsync() { inline bool Data::waitForVsync() {
// Call mdp waitForVsync
// Call mdp playWait if(!mMdp.waitForVsync()){
if(!this->playWait()){ ALOGE("Error in MDP %s", __FUNCTION__);
ALOGE("Error in MDP playWait");
return false; return false;
} }
return true; return true;
} }
inline bool Data::play() {
int fd = mMdp.getFd();
return mRot->enabled() ? mRot->play(fd) : mMdp.play();
}
inline bool Data::playWait() {
return mMdp.playWait();
}
inline void Data::dump() const { inline void Data::dump() const {
ALOGE("== Dump Data MDP start =="); ALOGE("== Dump Data MDP start ==");
mMdp.dump(); mMdp.dump();
mRot->dump();
ALOGE("== Dump Data MDP end =="); ALOGE("== Dump Data MDP end ==");
} }

View File

@@ -33,8 +33,6 @@
#include "overlayUtils.h" #include "overlayUtils.h"
#include "overlayRotator.h" #include "overlayRotator.h"
// FIXME make int to be uint32 whenever possible
namespace overlay { namespace overlay {
// Interface only. No member, no definiton (except ~ which can // Interface only. No member, no definiton (except ~ which can
@@ -44,8 +42,8 @@ public:
/* empty dtor. can be =0 with cpp impl*/ /* empty dtor. can be =0 with cpp impl*/
virtual ~OverlayImplBase() {} virtual ~OverlayImplBase() {}
/* Open pipe/rot for one dest */ /* Init pipe/rot for one dest */
virtual bool openPipe(RotatorBase* rot, utils::eDest dest) = 0; virtual bool initPipe(RotatorBase* rot, utils::eDest dest) = 0;
/* Close pipe/rot for all specified dest */ /* Close pipe/rot for all specified dest */
virtual bool closePipe(utils::eDest dest) = 0; virtual bool closePipe(utils::eDest dest) = 0;
@@ -53,12 +51,10 @@ public:
/* Copy specified pipe/rot from ov passed in (used by state machine only) */ /* Copy specified pipe/rot from ov passed in (used by state machine only) */
virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest) = 0; virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest) = 0;
/* TODO open func customized for RGBx pipes */ /* Init all pipes
* To init just one pipe, use initPipe()
/* Open all pipes
* To open just one pipe, use openPipe()
* */ * */
virtual bool open(RotatorBase* rot0, virtual bool init(RotatorBase* rot0,
RotatorBase* rot1, RotatorBase* rot1,
RotatorBase* rot2) = 0; RotatorBase* rot2) = 0;
@@ -72,12 +68,8 @@ public:
* */ * */
virtual bool commit(utils::eDest dest = utils::OV_PIPE_ALL) = 0; virtual bool commit(utils::eDest dest = utils::OV_PIPE_ALL) = 0;
/* Queue buffer with offset*/ /* Queue buffer with fd from an offset*/
virtual bool queueBuffer(uint32_t offset, virtual bool queueBuffer(int fd, uint32_t offset,
utils::eDest dest = utils::OV_PIPE_ALL) = 0;
/* For RGBx pipes, dequeue buffer (that is fb chunk)*/
virtual bool dequeueBuffer(void*& buf,
utils::eDest dest = utils::OV_PIPE_ALL) = 0; utils::eDest dest = utils::OV_PIPE_ALL) = 0;
/* Wait for vsync to be done on dest */ /* Wait for vsync to be done on dest */
@@ -93,16 +85,13 @@ public:
/* Set parameters - usually needed for Rotator, but would /* Set parameters - usually needed for Rotator, but would
* be passed down the stack as well */ * be passed down the stack as well */
virtual bool setParameter(const utils::Params& param, virtual bool setTransform(const utils::eTransform& param,
utils::eDest dest = utils::OV_PIPE_ALL) = 0; utils::eDest dest = utils::OV_PIPE_ALL) = 0;
/* Set new source including orientation */ /* Set new source including orientation */
virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES], virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES],
utils::eDest dest = utils::OV_PIPE_ALL) = 0; utils::eDest dest = utils::OV_PIPE_ALL) = 0;
/* set memory id to the underlying pipes */
virtual void setMemoryId(int id, utils::eDest dest = utils::OV_PIPE_ALL) = 0;
/* Get the overlay pipe type */ /* Get the overlay pipe type */
virtual utils::eOverlayPipeType getOvPipeType(utils::eDest dest) const = 0; virtual utils::eOverlayPipeType getOvPipeType(utils::eDest dest) const = 0;
@@ -112,22 +101,21 @@ public:
class NullPipe { class NullPipe {
public: public:
/* TODO open func customized for RGBx pipes */ bool init(RotatorBase* rot) { return true; }
bool open(RotatorBase* rot); bool close() { return true; }
bool close(); bool start(const utils::PipeArgs& args) { return true; }
bool start(const utils::PipeArgs& args); bool commit() { return true; }
bool commit(); bool setCrop(const utils::Dim& d) { return true; }
bool setCrop(const utils::Dim& d); bool setPosition(const utils::Dim& dim) { return true; }
bool setPosition(const utils::Dim& dim); bool setTransform(const utils::eTransform& param) { return true; }
bool setParameter(const utils::Params& param); bool setSource(const utils::PipeArgs& args) { return true; }
bool setSource(const utils::PipeArgs& args); bool queueBuffer(int fd, uint32_t offset) { return true; }
bool queueBuffer(uint32_t offset); bool waitForVsync() { return true; }
bool dequeueBuffer(void*& buf); // NullPipe will return by val here as opposed to other Pipes.
bool waitForVsync(); utils::eOverlayPipeType getOvPipeType() const {
void setMemoryId(int id); return utils::OV_PIPE_TYPE_NULL;
utils::PipeArgs getArgs() const; }
utils::eOverlayPipeType getOvPipeType() const; void dump() const {}
void dump() const;
}; };
/* /*
@@ -143,7 +131,6 @@ public:
/* ctor */ /* ctor */
OverlayImpl(); OverlayImpl();
OverlayImpl(P0* p0, P1* p1, P2* p2);
/* /*
* Comments of the below functions are the same as the one * Comments of the below functions are the same as the one
@@ -151,12 +138,11 @@ public:
* */ * */
virtual ~OverlayImpl(); virtual ~OverlayImpl();
virtual bool openPipe(RotatorBase* rot, utils::eDest dest); virtual bool initPipe(RotatorBase* rot, utils::eDest dest);
virtual bool closePipe(utils::eDest dest); virtual bool closePipe(utils::eDest dest);
virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest); virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest);
/* TODO open func customized for RGBx pipes */ virtual bool init(RotatorBase* rot0,
virtual bool open(RotatorBase* rot0,
RotatorBase* rot1, RotatorBase* rot1,
RotatorBase* rot2); RotatorBase* rot2);
virtual bool close(); virtual bool close();
@@ -165,16 +151,13 @@ public:
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
virtual bool setPosition(const utils::Dim& dim, virtual bool setPosition(const utils::Dim& dim,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
virtual bool setParameter(const utils::Params& param, virtual bool setTransform(const utils::eTransform& param,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES], virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES],
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
virtual bool queueBuffer(uint32_t offset, virtual bool queueBuffer(int fd, uint32_t offset,
utils::eDest dest = utils::OV_PIPE_ALL);
virtual bool dequeueBuffer(void*& buf,
utils::eDest dest = utils::OV_PIPE_ALL); utils::eDest dest = utils::OV_PIPE_ALL);
virtual bool waitForVsync(utils::eDest dest = utils::OV_PIPE1); virtual bool waitForVsync(utils::eDest dest = utils::OV_PIPE1);
virtual void setMemoryId(int id, utils::eDest dest = utils::OV_PIPE_ALL);
virtual utils::eOverlayPipeType getOvPipeType(utils::eDest dest) const; virtual utils::eOverlayPipeType getOvPipeType(utils::eDest dest) const;
virtual void dump() const; virtual void dump() const;
@@ -197,74 +180,97 @@ private:
//-----------Inlines and Template defn--------------------------------- //-----------Inlines and Template defn---------------------------------
/**** OverlayImpl ****/
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
OverlayImpl<P0, P1, P2>::OverlayImpl() : OverlayImpl<P0, P1, P2>::OverlayImpl() :
mPipe0(new P0), mPipe1(new P1), mPipe2(new P2), mPipe0(0), mPipe1(0), mPipe2(0),
mRotP0(0), mRotP1(0), mRotP2(0) mRotP0(0), mRotP1(0), mRotP2(0)
{} {
//Do not create a pipe here.
template <class P0, class P1, class P2> //Either initPipe can create a pipe OR
OverlayImpl<P0, P1, P2>::OverlayImpl(P0* p0, P1* p1, P2* p2) : //copyOvPipe can assign a pipe.
mPipe0(p0), mPipe1(p1), mPipe2(p2), }
mRotP0(0), mRotP1(0), mRotP2(0)
{}
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
OverlayImpl<P0, P1, P2>::~OverlayImpl() OverlayImpl<P0, P1, P2>::~OverlayImpl()
{ {
// no op in the meantime. needed to be clean //Do not delete pipes.
// since state machine will do delete. so we //closePipe will close and delete.
// do not want to close/delete pipes here
} }
/* Open only one pipe/rot pair per call */ /* Init only one pipe/rot pair per call */
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::openPipe(RotatorBase* rot, utils::eDest dest) bool OverlayImpl<P0, P1, P2>::initPipe(RotatorBase* rot, utils::eDest dest)
{ {
OVASSERT(rot, "%s: OverlayImpl rot is null", __FUNCTION__); OVASSERT(rot, "%s: OverlayImpl rot is null", __FUNCTION__);
OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d", OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d",
__FUNCTION__, dest); __FUNCTION__, dest);
// Need to down case rotator to mdp one.
// we assume p0/p1/p2/px all use the _same_ underlying mdp structure.
// FIXME STATIC_ASSERT here
bool ret = true; bool ret = true;
if (utils::OV_PIPE0 & dest) { if (utils::OV_PIPE0 & dest) {
OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "init pipe0");
ALOGE_IF(DEBUG_OVERLAY, "Open pipe0");
ret = mPipe0->open(rot);
mRotP0 = rot; mRotP0 = rot;
ret = mRotP0->init();
if(!ret) { if(!ret) {
ALOGE("%s: OverlayImpl pipe0 failed to open", __FUNCTION__); ALOGE("%s: OverlayImpl rot0 failed to init", __FUNCTION__);
return false;
} }
mPipe0 = new P0();
OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__);
ret = mPipe0->init(rot);
if(!ret) {
ALOGE("%s: OverlayImpl pipe0 failed to init", __FUNCTION__);
return false;
}
return ret; return ret;
} }
if (utils::OV_PIPE1 & dest) { if (utils::OV_PIPE1 & dest) {
OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "init pipe1");
ALOGE_IF(DEBUG_OVERLAY, "Open pipe1");
ret = mPipe1->open(rot);
mRotP1 = rot; mRotP1 = rot;
ret = mRotP1->init();
if(!ret) { if(!ret) {
ALOGE("%s: OverlayImpl pipe1 failed to open", __FUNCTION__); ALOGE("%s: OverlayImpl rot1 failed to init", __FUNCTION__);
return false;
} }
mPipe1 = new P1();
OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__);
ret = mPipe1->init(rot);
if(!ret) {
ALOGE("%s: OverlayImpl pipe1 failed to init", __FUNCTION__);
return false;
}
return ret; return ret;
} }
if (utils::OV_PIPE2 & dest) { if (utils::OV_PIPE2 & dest) {
OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "init pipe2");
ALOGE_IF(DEBUG_OVERLAY, "Open pipe2");
ret = mPipe2->open(rot);
mRotP2 = rot; mRotP2 = rot;
ret = mRotP2->init();
if(!ret) { if(!ret) {
ALOGE("%s: OverlayImpl pipe2 failed to open", __FUNCTION__); ALOGE("%s: OverlayImpl rot2 failed to init", __FUNCTION__);
return false;
} }
mPipe2 = new P2();
OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__);
ret = mPipe2->init(rot);
if(!ret) {
ALOGE("%s: OverlayImpl pipe2 failed to init", __FUNCTION__);
return false;
}
return ret; return ret;
} }
@@ -356,44 +362,48 @@ bool OverlayImpl<P0, P1, P2>::copyOvPipe(OverlayImplBase* ov,
if (utils::OV_PIPE0 & dest) { if (utils::OV_PIPE0 & dest) {
mPipe0 = ovimpl->mPipe0; mPipe0 = ovimpl->mPipe0;
mRotP0 = ovimpl->mRotP0; mRotP0 = ovimpl->mRotP0;
ovimpl->mPipe0 = 0;
ovimpl->mRotP0 = 0;
} }
if (utils::OV_PIPE1 & dest) { if (utils::OV_PIPE1 & dest) {
mPipe1 = ovimpl->mPipe1; mPipe1 = ovimpl->mPipe1;
mRotP1 = ovimpl->mRotP1; mRotP1 = ovimpl->mRotP1;
ovimpl->mPipe1 = 0;
ovimpl->mRotP1 = 0;
} }
if (utils::OV_PIPE2 & dest) { if (utils::OV_PIPE2 & dest) {
mPipe2 = ovimpl->mPipe2; mPipe2 = ovimpl->mPipe2;
mRotP2 = ovimpl->mRotP2; mRotP2 = ovimpl->mRotP2;
ovimpl->mPipe2 = 0;
ovimpl->mRotP2 = 0;
} }
return true; return true;
} }
/* TODO open func customized for RGBx pipes */ /* Init all pipes/rot */
/* Open all pipes/rot */
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::open(RotatorBase* rot0, bool OverlayImpl<P0, P1, P2>::init(RotatorBase* rot0,
RotatorBase* rot1, RotatorBase* rot1,
RotatorBase* rot2) RotatorBase* rot2)
{ {
if (!this->openPipe(rot0, utils::OV_PIPE0)) { if (!this->initPipe(rot0, utils::OV_PIPE0)) {
if (!this->close()) { if (!this->close()) {
ALOGE("%s: failed to close at least one pipe", __FUNCTION__); ALOGE("%s: failed to close at least one pipe", __FUNCTION__);
} }
return false; return false;
} }
if (!this->openPipe(rot1, utils::OV_PIPE1)) { if (!this->initPipe(rot1, utils::OV_PIPE1)) {
if (!this->close()) { if (!this->close()) {
ALOGE("%s: failed to close at least one pipe", __FUNCTION__); ALOGE("%s: failed to close at least one pipe", __FUNCTION__);
} }
return false; return false;
} }
if (!this->openPipe(rot2, utils::OV_PIPE2)) { if (!this->initPipe(rot2, utils::OV_PIPE2)) {
if (!this->close()) { if (!this->close()) {
ALOGE("%s: failed to close at least one pipe", __FUNCTION__); ALOGE("%s: failed to close at least one pipe", __FUNCTION__);
} }
@@ -509,7 +519,7 @@ bool OverlayImpl<P0, P1, P2>::setPosition(const utils::Dim& d,
} }
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::setParameter(const utils::Params& param, bool OverlayImpl<P0, P1, P2>::setTransform(const utils::eTransform& param,
utils::eDest dest) utils::eDest dest)
{ {
OVASSERT(mPipe0 && mPipe1 && mPipe2, OVASSERT(mPipe0 && mPipe1 && mPipe2,
@@ -517,21 +527,21 @@ bool OverlayImpl<P0, P1, P2>::setParameter(const utils::Params& param,
__FUNCTION__, mPipe0, mPipe1, mPipe2); __FUNCTION__, mPipe0, mPipe1, mPipe2);
if (utils::OV_PIPE0 & dest) { if (utils::OV_PIPE0 & dest) {
if(!mPipe0->setParameter(param)) { if(!mPipe0->setTransform(param)) {
ALOGE("OverlayImpl p0 failed to setparam"); ALOGE("OverlayImpl p0 failed to setparam");
return false; return false;
} }
} }
if (utils::OV_PIPE1 & dest) { if (utils::OV_PIPE1 & dest) {
if(!mPipe1->setParameter(param)) { if(!mPipe1->setTransform(param)) {
ALOGE("OverlayImpl p1 failed to setparam"); ALOGE("OverlayImpl p1 failed to setparam");
return false; return false;
} }
} }
if (utils::OV_PIPE2 & dest) { if (utils::OV_PIPE2 & dest) {
if(!mPipe2->setParameter(param)) { if(!mPipe2->setTransform(param)) {
ALOGE("OverlayImpl p2 failed to setparam"); ALOGE("OverlayImpl p2 failed to setparam");
return false; return false;
} }
@@ -541,7 +551,8 @@ bool OverlayImpl<P0, P1, P2>::setParameter(const utils::Params& param,
} }
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::setSource(const utils::PipeArgs args[utils::MAX_PIPES], bool OverlayImpl<P0, P1, P2>::setSource(
const utils::PipeArgs args[utils::MAX_PIPES],
utils::eDest dest) utils::eDest dest)
{ {
OVASSERT(mPipe0 && mPipe1 && mPipe2, OVASSERT(mPipe0 && mPipe1 && mPipe2,
@@ -573,28 +584,29 @@ bool OverlayImpl<P0, P1, P2>::setSource(const utils::PipeArgs args[utils::MAX_PI
} }
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::queueBuffer(uint32_t offset, utils::eDest dest) bool OverlayImpl<P0, P1, P2>::queueBuffer(int fd, uint32_t offset,
utils::eDest dest)
{ {
OVASSERT(mPipe0 && mPipe1 && mPipe2, OVASSERT(mPipe0 && mPipe1 && mPipe2,
"%s: Pipes are null p0=%p p1=%p p2=%p", "%s: Pipes are null p0=%p p1=%p p2=%p",
__FUNCTION__, mPipe0, mPipe1, mPipe2); __FUNCTION__, mPipe0, mPipe1, mPipe2);
if (utils::OV_PIPE0 & dest) { if (utils::OV_PIPE0 & dest) {
if(!mPipe0->queueBuffer(offset)) { if(!mPipe0->queueBuffer(fd, offset)) {
ALOGE("OverlayImpl p0 failed to queueBuffer"); ALOGE("OverlayImpl p0 failed to queueBuffer");
return false; return false;
} }
} }
if (utils::OV_PIPE1 & dest) { if (utils::OV_PIPE1 & dest) {
if(!mPipe1->queueBuffer(offset)) { if(!mPipe1->queueBuffer(fd, offset)) {
ALOGE("OverlayImpl p1 failed to queueBuffer"); ALOGE("OverlayImpl p1 failed to queueBuffer");
return false; return false;
} }
} }
if (utils::OV_PIPE2 & dest) { if (utils::OV_PIPE2 & dest) {
if(!mPipe2->queueBuffer(offset)) { if(!mPipe2->queueBuffer(fd, offset)) {
ALOGE("OverlayImpl p2 failed to queueBuffer"); ALOGE("OverlayImpl p2 failed to queueBuffer");
return false; return false;
} }
@@ -603,37 +615,6 @@ bool OverlayImpl<P0, P1, P2>::queueBuffer(uint32_t offset, utils::eDest dest)
return true; return true;
} }
template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::dequeueBuffer(void*& buf, utils::eDest dest)
{
OVASSERT(mPipe0 && mPipe1 && mPipe2,
"%s: Pipes are null p0=%p p1=%p p2=%p",
__FUNCTION__, mPipe0, mPipe1, mPipe2);
if (utils::OV_PIPE0 & dest) {
if(!mPipe0->dequeueBuffer(buf)) {
ALOGE("OverlayImpl p0 failed to dequeueBuffer");
return false;
}
}
if (utils::OV_PIPE1 & dest) {
if(!mPipe1->dequeueBuffer(buf)) {
ALOGE("OverlayImpl p1 failed to dequeueBuffer");
return false;
}
}
if (utils::OV_PIPE2 & dest) {
if(!mPipe2->dequeueBuffer(buf)) {
ALOGE("OverlayImpl p2 failed to dequeueBuffer");
return false;
}
}
return true;
}
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
bool OverlayImpl<P0, P1, P2>::waitForVsync(utils::eDest dest) bool OverlayImpl<P0, P1, P2>::waitForVsync(utils::eDest dest)
{ {
@@ -666,27 +647,8 @@ bool OverlayImpl<P0, P1, P2>::waitForVsync(utils::eDest dest)
} }
template <class P0, class P1, class P2> template <class P0, class P1, class P2>
void OverlayImpl<P0, P1, P2>::setMemoryId(int id, utils::eDest dest) utils::eOverlayPipeType OverlayImpl<P0, P1, P2>::getOvPipeType(
{ utils::eDest dest) const
OVASSERT(mPipe0 && mPipe1 && mPipe2,
"%s: Pipes are null p0=%p p1=%p p2=%p",
__FUNCTION__, mPipe0, mPipe1, mPipe2);
if (utils::OV_PIPE0 & dest) {
mPipe0->setMemoryId(id);
}
if (utils::OV_PIPE1 & dest) {
mPipe1->setMemoryId(id);
}
if (utils::OV_PIPE2 & dest) {
mPipe2->setMemoryId(id);
}
}
template <class P0, class P1, class P2>
utils::eOverlayPipeType OverlayImpl<P0, P1, P2>::getOvPipeType(utils::eDest dest) const
{ {
OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d", OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d",
__FUNCTION__, dest); __FUNCTION__, dest);

View File

@@ -23,11 +23,11 @@
namespace ovutils = overlay::utils; namespace ovutils = overlay::utils;
namespace overlay { namespace overlay {
bool MdpCtrl::open(uint32_t fbnum) { bool MdpCtrl::init(uint32_t fbnum) {
// FD open // FD init
if(!utils::openDev(mFd, fbnum, if(!utils::openDev(mFd, fbnum,
Res::devTemplate, O_RDWR)){ Res::fbPath, O_RDWR)){
ALOGE("Ctrl failed to open fbnum=%d", fbnum); ALOGE("Ctrl failed to init fbnum=%d", fbnum);
return false; return false;
} }
return true; return true;
@@ -36,12 +36,15 @@ bool MdpCtrl::open(uint32_t fbnum) {
void MdpCtrl::reset() { void MdpCtrl::reset() {
utils::memset0(mOVInfo); utils::memset0(mOVInfo);
utils::memset0(mLkgo); utils::memset0(mLkgo);
mOVInfo.id = -1; mOVInfo.id = MSMFB_NEW_REQUEST;
mLkgo.id = -1; mLkgo.id = MSMFB_NEW_REQUEST;
mOrientation = utils::OVERLAY_TRANSFORM_0;
mRotUsed = false;
} }
bool MdpCtrl::close() { bool MdpCtrl::close() {
if(-1 == static_cast<int>(mOVInfo.id)) return true; if(MSMFB_NEW_REQUEST == static_cast<int>(mOVInfo.id))
return true;
if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) { if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
ALOGE("MdpCtrl close error in unset"); ALOGE("MdpCtrl close error in unset");
return false; return false;
@@ -53,6 +56,86 @@ bool MdpCtrl::close() {
return true; return true;
} }
bool MdpCtrl::setSource(const utils::PipeArgs& args) {
setSrcWhf(args.whf);
//TODO These are hardcoded. Can be moved out of setSource.
mOVInfo.alpha = 0xff;
mOVInfo.transp_mask = 0xffffffff;
//TODO These calls should ideally be a part of setPipeParams API
setFlags(args.mdpFlags);
setZ(args.zorder);
setIsFg(args.isFg);
return true;
}
bool MdpCtrl::setCrop(const utils::Dim& d) {
setSrcRectDim(d);
return true;
}
bool MdpCtrl::setPosition(const overlay::utils::Dim& d,
int fbw, int fbh)
{
ovutils::Dim dim(d);
ovutils::Dim ovsrcdim = getSrcRectDim();
// Scaling of upto a max of 20 times supported
if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){
dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w;
dim.x = (fbw - dim.w) / 2;
}
if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) {
dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h;
dim.y = (fbh - dim.h) / 2;
}
setDstRectDim(dim);
return true;
}
bool MdpCtrl::setTransform(const utils::eTransform& orient,
const bool& rotUsed) {
mOrientation = orient;
int rot = utils::getMdpOrient(orient);
setUserData(rot);
//Rotator can be requested by client even if layer has 0 orientation.
mRotUsed = rotUsed;
return true;
}
void MdpCtrl::doTransform() {
adjustSrcWhf(mRotUsed);
setRotationFlags();
//180 will be H + V
//270 will be H + V + 90
if(mOrientation & utils::OVERLAY_TRANSFORM_FLIP_H) {
overlayTransFlipH();
}
if(mOrientation & utils::OVERLAY_TRANSFORM_FLIP_V) {
overlayTransFlipV();
}
if(mOrientation & utils::OVERLAY_TRANSFORM_ROT_90) {
overlayTransRot90();
}
}
bool MdpCtrl::set() {
//deferred calcs, so APIs could be called in any order.
doTransform();
if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
ALOGE("MdpCtrl failed to setOverlay, restoring last known "
"good ov info");
mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
this->restore();
return false;
}
this->save();
return true;
}
bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) { bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) {
fb_fix_screeninfo finfo; fb_fix_screeninfo finfo;
if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) { if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) {
@@ -81,193 +164,24 @@ bool MdpCtrl::get() {
return true; return true;
} }
// that is the second part of original setParameter function //Adjust width, height, format if rotator is used.
void MdpCtrl::setSrcFormat(const utils::Whf& whf) { void MdpCtrl::adjustSrcWhf(const bool& rotUsed) {
if(rotUsed) {
//By default mdp src format is the same as buffer's utils::Whf whf = getSrcWhf();
mOVInfo.src.format = whf.format;
//If rotation is used and input formats are tiled then output of rotator is
//non-tiled.
// FIXME mRotInfo.enable = 1; for enable
if (getUserData()) { // if rotations enabled in MdpCtrl
if (whf.format == MDP_Y_CRCB_H2V2_TILE)
mOVInfo.src.format = MDP_Y_CRCB_H2V2;
else if (whf.format == MDP_Y_CBCR_H2V2_TILE)
mOVInfo.src.format = MDP_Y_CBCR_H2V2;
return;
}
}
bool MdpCtrl::set() {
if(!this->ovChanged()) {
return true; // nothing todo here.
}
if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) {
ALOGE("MdpCtrl failed to setOverlay, restoring last known "
"good ov info");
mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo);
mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo);
this->restore();
// FIXME, do we need to set the old one?
return false;
}
this->save();
return true;
}
bool MdpCtrl::setPosition(const overlay::utils::Dim& d,
int fbw, int fbh)
{
// Validatee against FB size
if(!d.check(fbw, fbh)) {
ALOGE("MdpCtrl setPosition failed dest dim violate screen limits");
return false;
}
ovutils::Dim dim(d);
ovutils::Dim ovsrcdim = getSrcRectDim();
// Scaling of upto a max of 8 times supported
if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){
dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w;
dim.x = (fbw - dim.w) / 2;
}
if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) {
dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h;
dim.y = (fbh - dim.h) / 2;
}
//dim.even_out();
setDstRectDim(dim);
return true;
}
void MdpCtrl::updateSource(RotatorBase* r,
const utils::PipeArgs& args,
const utils::ScreenInfo& info) {
utils::Whf whf(args.whf);
mOVInfo.src.width = whf.w;
mOVInfo.src.height = whf.h;
mOVInfo.src_rect.x = 0;
mOVInfo.src_rect.y = 0;
mOVInfo.dst_rect.x = 0;
mOVInfo.dst_rect.y = 0;
mOVInfo.dst_rect.w = whf.w;
mOVInfo.dst_rect.h = whf.h;
mOVInfo.src.format = whf.format;
if(whf.format == MDP_Y_CRCB_H2V2_TILE || if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
(whf.format == MDP_Y_CBCR_H2V2_TILE)) { whf.format == MDP_Y_CBCR_H2V2_TILE) {
// passing by value, setInfo fills it and return by val whf.w = utils::alignup(whf.w, 64);
mOVInfo = r->setInfo(args, mOVInfo); whf.h = utils::alignup(whf.h, 32);
} else {
mOVInfo.src_rect.w = whf.w;
mOVInfo.src_rect.h = whf.h;
} }
//For example: If original format is tiled, rotator outputs non-tiled,
if (whf.w > info.mFBWidth) //so update mdp's src fmt to that.
mOVInfo.dst_rect.w = info.mFBWidth; whf.format = utils::getRotOutFmt(whf.format);
if (whf.h > info.mFBHeight) setSrcWhf(whf);
mOVInfo.dst_rect.h = info.mFBHeight;
mSize = whf.size;
}
bool MdpCtrl::setInfo(RotatorBase* r,
const utils::PipeArgs& args,
const utils::ScreenInfo& info)
{
// new request
utils::Whf whf(args.whf);
mOVInfo.id = MSMFB_NEW_REQUEST;
updateSource(r, args, info);
setUserData(0);
mOVInfo.alpha = 0xff;
mOVInfo.transp_mask = 0xffffffff;
setZ(args.zorder);
setFlags(args.mdpFlags);
setWait(args.wait);
setIsFg(args.isFg);
mSize = whf.size;
return true;
}
bool MdpCtrl::setCrop(const utils::Dim& cdim) {
utils::Dim d(cdim);
const utils::Whf ovwhf = getSrcWhf();
int udata = getUserData();
switch(udata) {
case MDP_ROT_NOP:
break; // nothing to do here
case MDP_ROT_90:
case MDP_ROT_90 | MDP_FLIP_UD:
case MDP_ROT_90 | MDP_FLIP_LR:
{
if (ovwhf.w < (d.y + d.h)) {
ALOGE("MdpCtrl setCrop failed ROT 90 udata=%d",
udata);
d.dump();
this->dump();
return false;
} }
uint32_t tmp = d.x;
d.x = ovwhf.w - (d.y + d.h);
d.y = tmp;
utils::swap(d.w, d.h);
}break;
case MDP_ROT_270:
{
if (ovwhf.h < (d.x + d.w)) {
ALOGE("MdpCtrl setCrop failed ROT 270 udata=%d",
udata);
d.dump();
this->dump();
return false;
}
uint32_t tmp = d.y;
d.y = ovwhf.h - (d.x + d.w);
d.x = tmp;
utils::swap(d.w, d.h);
}break;
case MDP_ROT_180:
{
if ((ovwhf.h < (d.y + d.h)) ||
(ovwhf.w < ( d.x + d.w))) {
ALOGE("MdpCtrl setCrop failed ROT 180 udata=%d",
udata);
d.dump();
this->dump();
return false;
}
d.x = ovwhf.w - (d.x + d.w);
d.y = ovwhf.h - (d.y + d.h);
}break;
default:
if(!(udata & (MDP_FLIP_UD | MDP_FLIP_LR))) {
ALOGE("MdpCtrl setCrop unknown rot %d", udata);
return false;
}
}
if(getSrcRectDim() == d) {
return true; // Nothing to do here
}
utils::normalizeCrop(d.x, d.w);
utils::normalizeCrop(d.y, d.h);
setSrcRectDim(d);
return true;
} }
void MdpCtrl::dump() const { void MdpCtrl::dump() const {
ALOGE("== Dump MdpCtrl start =="); ALOGE("== Dump MdpCtrl start ==");
ALOGE("size=%d", mSize);
mFd.dump(); mFd.dump();
mdp_wrapper::dump("mOVInfo", mOVInfo); mdp_wrapper::dump("mOVInfo", mOVInfo);
ALOGE("== Dump MdpCtrl end =="); ALOGE("== Dump MdpCtrl end ==");

View File

@@ -22,12 +22,9 @@
#include "overlayUtils.h" #include "overlayUtils.h"
#include "mdpWrapper.h" #include "mdpWrapper.h"
#include "overlayRotator.h"
namespace overlay{ namespace overlay{
class RotatorBase;
/* /*
* Mdp Ctrl holds corresponding fd and MDP related struct. * Mdp Ctrl holds corresponding fd and MDP related struct.
* It is simple wrapper to MDP services * It is simple wrapper to MDP services
@@ -40,20 +37,20 @@ public:
/* dtor close */ /* dtor close */
~MdpCtrl(); ~MdpCtrl();
/* Open underlying device using fbnum */ /* init underlying device using fbnum */
bool open(uint32_t fbnum); bool init(uint32_t fbnum);
/* unset overlay, reset and close fd */ /* unset overlay, reset and close fd */
bool close(); bool close();
/* reset and set ov id to -1*/ /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
void reset(); void reset();
/* get orient / user_data[0] */ /* get orient / user_data[0] */
int getOrient() const; int getOrient() const;
/* returns session id */ /* returns session id */
int getId() const; int getPipeId() const;
/* returns the fd associated to ctrl*/ /* returns the fd associated to ctrl*/
int getFd() const; int getFd() const;
@@ -64,29 +61,15 @@ public:
/* overlay get */ /* overlay get */
bool get(); bool get();
/* returns flags from mdp structure. /* returns flags from mdp structure */
* Flags are WAIT/NOWAIT/PIPE SHARED*/
int getFlags() const; int getFlags() const;
/* set flags to mdp structure */ /* set flags to mdp structure */
void setFlags(int f); void setFlags(int f);
/* code taken from OverlayControlChannel::setOverlayInformation */
bool setInfo(RotatorBase* r,
const utils::PipeArgs& args,
const utils::ScreenInfo& info);
/* given whf, update src */
void updateSource(RotatorBase* r,
const utils::PipeArgs& args,
const utils::ScreenInfo& info);
/* set z order */ /* set z order */
void setZ(utils::eZorder z); void setZ(utils::eZorder z);
/* set Wait/nowait */
void setWait(utils::eWait wait);
/* set isFg flag */ /* set isFg flag */
void setIsFg(utils::eIsFg isFg); void setIsFg(utils::eIsFg isFg);
@@ -102,8 +85,8 @@ public:
/* set src whf */ /* set src whf */
void setSrcWhf(const utils::Whf& whf); void setSrcWhf(const utils::Whf& whf);
/* set source format based on rot info */ /* adjust source width height format based on rot info */
void setSrcFormat(const utils::Whf& whf); void adjustSrcWhf(const bool& rotUsed);
/* swap src w/h*/ /* swap src w/h*/
void swapSrcWH(); void swapSrcWH();
@@ -128,7 +111,7 @@ public:
void setUserData(int v); void setUserData(int v);
/* return true if current overlay is different /* return true if current overlay is different
* than lask known good overlay */ * than last known good overlay */
bool ovChanged() const; bool ovChanged() const;
/* save mOVInfo to be last known good ov*/ /* save mOVInfo to be last known good ov*/
@@ -137,6 +120,9 @@ public:
/* restore last known good ov to be the current */ /* restore last known good ov to be the current */
void restore(); void restore();
/* Sets the source total width, height, format */
bool setSource(const utils::PipeArgs& pargs);
/* /*
* Sets ROI, the unpadded region, for source buffer. * Sets ROI, the unpadded region, for source buffer.
* Should be called before a setPosition, for small clips. * Should be called before a setPosition, for small clips.
@@ -144,6 +130,8 @@ public:
*/ */
bool setCrop(const utils::Dim& d); bool setCrop(const utils::Dim& d);
bool setTransform(const utils::eTransform& orient, const bool& rotUsed);
/* given a dim and w/h, set overlay dim */ /* given a dim and w/h, set overlay dim */
bool setPosition(const utils::Dim& dim, int w, int h); bool setPosition(const utils::Dim& dim, int w, int h);
@@ -152,8 +140,19 @@ public:
/* dump state of the object */ /* dump state of the object */
void dump() const; void dump() const;
private: private:
/* helper functions for overlayTransform */
void doTransform();
void overlayTransFlipH();
void overlayTransFlipV();
void overlayTransRot90();
utils::eTransform mOrientation; //Holds requested orientation
bool mRotUsed; //whether rotator should be used even if requested
//orientation is 0.
/* last good known ov info */ /* last good known ov info */
mdp_overlay mLkgo; mdp_overlay mLkgo;
@@ -162,9 +161,6 @@ private:
/* FD for the mdp fbnum */ /* FD for the mdp fbnum */
OvFD mFd; OvFD mFd;
/* cached size FIXME do we need it? */
uint32_t mSize;
}; };
@@ -201,8 +197,8 @@ public:
/* dtor close*/ /* dtor close*/
~MdpData(); ~MdpData();
/* open FD */ /* init FD */
bool open(uint32_t fbnum); bool init(uint32_t fbnum);
/* memset0 the underlying mdp object */ /* memset0 the underlying mdp object */
void reset(); void reset();
@@ -210,29 +206,23 @@ public:
/* close fd, and reset */ /* close fd, and reset */
bool close(); bool close();
/* Set FD / memid */
void setMemoryId(int id);
/* set id of mdp data */ /* set id of mdp data */
void setId(int id); void setPipeId(int id);
/* return ses id of data */ /* return ses id of data */
int getId() const; int getPipeId() const;
/* get underlying fd*/ /* get underlying fd*/
int getFd() const; int getFd() const;
/* get memory_id */ /* get memory_id */
int getMemoryId() const; int getSrcMemoryId() const;
/* set offset in underlying mdp obj */
void setOffset(uint32_t o);
/* calls wrapper play */ /* calls wrapper play */
bool play(); bool play(int fd, uint32_t offset);
/* calls wrapper playWait */ /* calls wrapper waitForVsync */
bool playWait(); bool waitForVsync();
/* dump state of the object */ /* dump state of the object */
void dump() const; void dump() const;
@@ -247,21 +237,22 @@ private:
//--------------Inlines--------------------------------- //--------------Inlines---------------------------------
namespace utils { namespace utils {
inline bool openDev(OvFD& fd, int fb, inline bool openDev(OvFD& fd, int fbnum,
const char* const s, const char* const devpath,
int flags) { int flags) {
return overlay::open(fd, fb, Res::devTemplate, O_RDWR); return overlay::open(fd, fbnum, devpath, flags);
} }
}
namespace {
// just a helper func for common operations x-(y+z)
int compute(uint32_t x, uint32_t y, uint32_t z) {
return x-(y+z);
}
} }
template <class T>
inline void init(T& t) {
memset(&t, 0, sizeof(T));
}
///// MdpCtrl ////// ///// MdpCtrl //////
inline MdpCtrl::MdpCtrl() : mSize(0) { inline MdpCtrl::MdpCtrl() {
reset(); reset();
} }
@@ -273,7 +264,7 @@ inline int MdpCtrl::getOrient() const {
return getUserData(); return getUserData();
} }
inline int MdpCtrl::getId() const { inline int MdpCtrl::getPipeId() const {
return mOVInfo.id; return mOVInfo.id;
} }
@@ -293,10 +284,6 @@ inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
mOVInfo.z_order = z; mOVInfo.z_order = z;
} }
inline void MdpCtrl::setWait(overlay::utils::eWait wait) {
mOVInfo.flags = utils::setWait(wait, mOVInfo.flags);
}
inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) { inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
mOVInfo.is_fg = isFg; mOVInfo.is_fg = isFg;
} }
@@ -310,25 +297,23 @@ inline bool MdpCtrl::ovChanged() const {
} }
inline void MdpCtrl::save() { inline void MdpCtrl::save() {
if(static_cast<ssize_t>(mOVInfo.id) == -1) { if(static_cast<ssize_t>(mOVInfo.id) == MSMFB_NEW_REQUEST) {
ALOGE("MdpCtrl current ov has id -1, will not save"); ALOGE("MdpCtrl current ov has id -1, will not save");
// FIXME dump both?
return; return;
} }
mLkgo = mOVInfo; mLkgo = mOVInfo;
} }
inline void MdpCtrl::restore() { inline void MdpCtrl::restore() {
if(static_cast<ssize_t>(mLkgo.id) == -1) { if(static_cast<ssize_t>(mLkgo.id) == MSMFB_NEW_REQUEST) {
ALOGE("MdpCtrl Lkgo ov has id -1, will not restore"); ALOGE("MdpCtrl Lkgo ov has id -1, will not restore");
// FIXME dump both?
return; return;
} }
mOVInfo = mLkgo; mOVInfo = mLkgo;
} }
inline overlay::utils::Whf MdpCtrl::getSrcWhf() const { inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
return utils::Whf(mOVInfo.src.width, return utils::Whf( mOVInfo.src.width,
mOVInfo.src.height, mOVInfo.src.height,
mOVInfo.src.format); mOVInfo.src.format);
} }
@@ -340,7 +325,7 @@ inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
} }
inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const { inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
return utils::Dim(mOVInfo.src_rect.x, return utils::Dim( mOVInfo.src_rect.x,
mOVInfo.src_rect.y, mOVInfo.src_rect.y,
mOVInfo.src_rect.w, mOVInfo.src_rect.w,
mOVInfo.src_rect.h); mOVInfo.src_rect.h);
@@ -354,7 +339,7 @@ inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
} }
inline overlay::utils::Dim MdpCtrl::getDstRectDim() const { inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
return utils::Dim(mOVInfo.dst_rect.x, return utils::Dim( mOVInfo.dst_rect.x,
mOVInfo.dst_rect.y, mOVInfo.dst_rect.y,
mOVInfo.dst_rect.w, mOVInfo.dst_rect.w,
mOVInfo.dst_rect.h); mOVInfo.dst_rect.h);
@@ -379,14 +364,46 @@ inline void MdpCtrl::setRotationFlags() {
mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90; mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90;
} }
inline void MdpCtrl::swapSrcWH() { inline void MdpCtrl::swapSrcWH() {
utils::swap(mOVInfo.src.width, utils::swap(mOVInfo.src.width,
mOVInfo.src.height); } mOVInfo.src.height);
}
inline void MdpCtrl::swapSrcRectWH() { inline void MdpCtrl::swapSrcRectWH() {
utils::swap(mOVInfo.src_rect.h, utils::swap(mOVInfo.src_rect.w,
mOVInfo.src_rect.w); } mOVInfo.src_rect.h);
}
inline void MdpCtrl::overlayTransFlipH()
{
utils::Dim d = getSrcRectDim();
utils::Whf whf = getSrcWhf();
d.x = compute(whf.w, d.x, d.w);
setSrcRectDim(d);
}
inline void MdpCtrl::overlayTransFlipV()
{
utils::Dim d = getSrcRectDim();
utils::Whf whf = getSrcWhf();
d.y = compute(whf.h, d.y, d.h);
setSrcRectDim(d);
}
inline void MdpCtrl::overlayTransRot90()
{
utils::Dim d = getSrcRectDim();
utils::Whf whf = getSrcWhf();
int tmp = d.x;
d.x = compute(whf.h,
d.y,
d.h);
d.y = tmp;
setSrcRectDim(d);
swapSrcWH();
swapSrcRectWH();
}
/////// MdpCtrl3D ////// /////// MdpCtrl3D //////
@@ -434,10 +451,10 @@ inline MdpData::MdpData() { reset(); }
inline MdpData::~MdpData() { close(); } inline MdpData::~MdpData() { close(); }
inline bool MdpData::open(uint32_t fbnum) { inline bool MdpData::init(uint32_t fbnum) {
// FD open // FD init
if(!utils::openDev(mFd, fbnum, Res::devTemplate, O_RDWR)){ if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
ALOGE("Ctrl failed to open fbnum=%d", fbnum); ALOGE("Ctrl failed to init fbnum=%d", fbnum);
return false; return false;
} }
return true; return true;
@@ -457,28 +474,29 @@ inline bool MdpData::close() {
return true; return true;
} }
inline void MdpData::setMemoryId(int id) { mOvData.data.memory_id = id; } inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
inline int MdpData::getMemoryId() const { return mOvData.data.memory_id; }
inline void MdpData::setId(int id) { mOvData.id = id; } inline void MdpData::setPipeId(int id) { mOvData.id = id; }
inline int MdpData::getId() const { return mOvData.id; } inline int MdpData::getPipeId() const { return mOvData.id; }
inline int MdpData::getFd() const { return mFd.getFD(); } inline int MdpData::getFd() const { return mFd.getFD(); }
inline void MdpData::setOffset(uint32_t o) { mOvData.data.offset = o; } inline bool MdpData::play(int fd, uint32_t offset) {
mOvData.data.memory_id = fd;
inline bool MdpData::play() { mOvData.data.offset = offset;
if(!mdp_wrapper::play(mFd.getFD(), mOvData)){ if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
ALOGE("MdpData failed to play"); ALOGE("MdpData failed to play");
dump();
return false; return false;
} }
return true; return true;
} }
inline bool MdpData::playWait() { inline bool MdpData::waitForVsync() {
if(!mdp_wrapper::playWait(mFd.getFD(), mOvData)){ if(!mdp_wrapper::waitForVsync(mFd.getFD(), mOvData)){
ALOGE("MdpData failed to playWait"); ALOGE("%s failed", __FUNCTION__);
dump();
return false; return false;
} }
return true; return true;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@@ -54,7 +54,7 @@ public:
/* Use libgralloc to retrieve fd, base addr, alloc type */ /* Use libgralloc to retrieve fd, base addr, alloc type */
bool open(uint32_t numbufs, bool open(uint32_t numbufs,
uint32_t bufSz, int flags = O_RDWR); uint32_t bufSz, bool isSecure);
/* close fd. assign base address to invalid*/ /* close fd. assign base address to invalid*/
bool close(); bool close();
@@ -115,14 +115,16 @@ inline OvMem::OvMem() {
inline OvMem::~OvMem() { } inline OvMem::~OvMem() { }
inline bool OvMem::open(uint32_t numbufs, inline bool OvMem::open(uint32_t numbufs,
uint32_t bufSz, int flags) uint32_t bufSz, bool isSecure)
{ {
alloc_data data; alloc_data data;
//XXX: secure buffers and IOMMU heap int allocFlags = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP | if(isSecure) {
GRALLOC_USAGE_PRIVATE_DO_NOT_MAP; allocFlags |= GRALLOC_USAGE_PRIVATE_MM_HEAP;
int err = 0; allocFlags |= GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
}
int err = 0;
OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz); OVASSERT(numbufs && bufSz, "numbufs=%d bufSz=%d", numbufs, bufSz);
mBufSz = bufSz; mBufSz = bufSz;
@@ -138,6 +140,7 @@ inline bool OvMem::open(uint32_t numbufs,
err = mAlloc->allocate(data, allocFlags, 0); err = mAlloc->allocate(data, allocFlags, 0);
if (err != 0) { if (err != 0) {
ALOGE("OvMem: error allocating memory"); ALOGE("OvMem: error allocating memory");
return false;
} }
mFd = data.fd; mFd = data.fd;
@@ -159,6 +162,7 @@ inline bool OvMem::close()
ret = memalloc->free_buffer(mBaseAddr, mBufSz * mNumBuffers, 0, mFd); ret = memalloc->free_buffer(mBaseAddr, mBufSz * mNumBuffers, 0, mFd);
if (ret != 0) { if (ret != 0) {
ALOGE("OvMem: error freeing buffer"); ALOGE("OvMem: error freeing buffer");
return false;
} }
mFd = -1; mFd = -1;
@@ -166,7 +170,7 @@ inline bool OvMem::close()
mAllocType = 0; mAllocType = 0;
mBufSz = 0; mBufSz = 0;
mNumBuffers = 0; mNumBuffers = 0;
return ret; return true;
} }
inline bool OvMem::valid() const inline bool OvMem::valid() const
@@ -196,8 +200,9 @@ inline uint32_t OvMem::numBufs() const
inline void OvMem::dump() const inline void OvMem::dump() const
{ {
ALOGE("%s: fd=%d addr=%p type=%d bufsz=%u", ALOGE("== Dump OvMem start ==");
__FUNCTION__, mFd, mBaseAddr, mAllocType, mBufSz); ALOGE("fd=%d addr=%p type=%d bufsz=%u", mFd, mBaseAddr, mAllocType, mBufSz);
ALOGE("== Dump OvMem end ==");
} }
} // overlay } // overlay

View File

@@ -17,72 +17,110 @@
#include "overlayRotator.h" #include "overlayRotator.h"
#include "overlayUtils.h" #include "overlayUtils.h"
#include "overlayMdp.h"
namespace ovutils = overlay::utils; namespace ovutils = overlay::utils;
namespace overlay { namespace overlay {
namespace utils { int IRotatorHw::getRotatorHwType() {
inline mdp_overlay setInfoNullRot(const utils::PipeArgs& args, //TODO figure out based on ioctl
const mdp_overlay& o) return TYPE_MDP;
{
mdp_overlay ov = o;
utils::Whf whf(args.whf);
utils::Dim d(utils::getSrcRectDim(ov));
d.w = whf.w - (utils::alignup(whf.w, 64) - whf.w);
d.h = whf.h - (utils::alignup(whf.h, 32) - whf.h);
utils::setSrcRectDim(ov, d);
return ov;
} }
inline mdp_overlay setInfoRot(const utils::PipeArgs& args, bool RotMem::close() {
const mdp_overlay& o) bool ret = true;
{ for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
/* If there are no orientation, then we use setInfoRot // skip current, and if valid, close
* That is even if we are a real rotator object (not null) if(m[i].valid()) {
* Note, that if args.rotFlags are ENABLED if(m[i].close() == false) {
* it means we would still like to have rot ALOGE("%s error in closing rot mem %d", __FUNCTION__, i);
* even though it is ROT_0 */ ret = false;
if(OVERLAY_TRANSFORM_0 == args.orientation &&
utils::ROT_FLAG_ENABLED != args.rotFlags) {
return setInfoNullRot(args, o);
} }
}
mdp_overlay ov = o; }
utils::Whf whf(args.whf); return ret;
utils::Dim d(utils::getSrcRectDim(ov));
d.w = whf.w;
d.h = whf.h;
utils::Whf localwhf (utils::getSrcWhf(ov));
localwhf.w = utils::alignup(whf.w, 64);
localwhf.h = utils::alignup(whf.h, 32);
d.x = localwhf.w - whf.w;
d.y = localwhf.h - whf.h;
utils::setSrcRectDim(ov, d);
utils::setSrcWhf(ov, localwhf);
return ov;
} }
} // utils bool MdpRot::init()
bool MdpRot::open()
{ {
if(!mFd.open(Res::rotPath, O_RDWR)){ if(!mFd.open(Res::rotPath, O_RDWR)){
ALOGE("MdpRot failed to open %s", Res::rotPath); ALOGE("MdpRot failed to init %s", Res::rotPath);
return false; return false;
} }
return true; return true;
} }
void MdpRot::setSource(const overlay::utils::Whf& awhf) {
utils::Whf whf(awhf);
mRotImgInfo.src.format = whf.format;
if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
whf.format == MDP_Y_CBCR_H2V2_TILE) {
whf.w = utils::alignup(awhf.w, 64);
whf.h = utils::alignup(awhf.h, 32);
}
mRotImgInfo.src.width = whf.w;
mRotImgInfo.src.height = whf.h;
mRotImgInfo.src_rect.w = whf.w;
mRotImgInfo.src_rect.h = whf.h;
mRotImgInfo.dst.width = whf.w;
mRotImgInfo.dst.height = whf.h;
mBufSize = awhf.size;
}
void MdpRot::setFlags(const utils::eMdpFlags& flags) {
mRotImgInfo.secure = 0;
if(flags & utils::OV_MDP_SECURE_OVERLAY_SESSION)
mRotImgInfo.secure = 1;
}
void MdpRot::setTransform(const utils::eTransform& rot, const bool& rotUsed)
{
mOrientation = rot;
int r = utils::getMdpOrient(rot);
ALOGE_IF(DEBUG_OVERLAY, "%s: r=%d", __FUNCTION__, r);
setRotations(r);
setDisable();
if(rotUsed) {
setEnable();
}
}
void MdpRot::doTransform() {
switch(mOrientation) {
case utils::OVERLAY_TRANSFORM_ROT_90:
case utils::OVERLAY_TRANSFORM_ROT_90_FLIP_H:
case utils::OVERLAY_TRANSFORM_ROT_90_FLIP_V:
case utils::OVERLAY_TRANSFORM_ROT_270:
utils::swap(mRotImgInfo.dst.width, mRotImgInfo.dst.height);
break;
default:
break;
}
}
bool MdpRot::commit() {
doTransform();
if(!overlay::mdp_wrapper::startRotator(mFd.getFD(), mRotImgInfo)) {
ALOGE("MdpRot commit failed");
dump();
return false;
}
mRotDataInfo.session_id = mRotImgInfo.session_id;
return true;
}
bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz) bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz)
{ {
OvMem mem; OvMem mem;
OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i"); OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i");
if(!mem.open(numbufs, bufsz)){ if(!mem.open(numbufs, bufsz, mRotImgInfo.secure)){
ALOGE("%s: Failed to open", __func__); ALOGE("%s: Failed to open", __func__);
mem.close(); mem.close();
return false; return false;
@@ -91,25 +129,12 @@ bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz)
OVASSERT(MAP_FAILED != mem.addr(), "MAP failed"); OVASSERT(MAP_FAILED != mem.addr(), "MAP failed");
OVASSERT(mem.getFD() != -1, "getFd is -1"); OVASSERT(mem.getFD() != -1, "getFd is -1");
mData.data.memory_id = mem.getFD();
mRotDataInfo.dst.memory_id = mem.getFD(); mRotDataInfo.dst.memory_id = mem.getFD();
mRotDataInfo.dst.offset = 0; mRotDataInfo.dst.offset = 0;
mMem.curr().m = mem; mMem.curr().m = mem;
return true; return true;
} }
bool MdpRot::RotMem::close() {
bool ret = true;
for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
// skip current, and if valid, close
if(m[i].valid() && (m[i].close() != 0)) {
ALOGE("%s error in closing prev rot mem %d", __FUNCTION__, i);
ret = false;
}
}
return ret;
}
bool MdpRot::close() { bool MdpRot::close() {
bool success = true; bool success = true;
if(mFd.valid() && (getSessId() > 0)) { if(mFd.valid() && (getSessId() > 0)) {
@@ -131,300 +156,78 @@ bool MdpRot::close() {
return success; return success;
} }
bool MdpRot::unmapNonCurrent() { bool MdpRot::remap(uint32_t numbufs) {
bool ret = true;
for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) {
// skip current, and if valid, close
if(i != mMem._curr % RotMem::MAX_ROT_MEM &&
mMem.m[i].valid() &&
!mMem.m[i].close()) {
ALOGE("%s error in closing prev rot mem %d", __FUNCTION__, i);
ret = false;
}
}
return ret;
}
bool MdpRot::remap(uint32_t numbufs,
const utils::PipeArgs& args) {
// if current size changed, remap // if current size changed, remap
if(args.whf.size == mMem.curr().size()) { if(mBufSize == mMem.curr().size()) {
ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, args.whf.size); ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, mBufSize);
return true;
}
// remap only if we have orientation.
// If rotFlags are ENABLED, it means we need rotation bufs
// even when orientation is 0
if(utils::OVERLAY_TRANSFORM_0 == args.orientation &&
utils::ROT_FLAG_ENABLED != args.rotFlags) {
ALOGE_IF(DEBUG_OVERLAY, "%s: orientation=%d, rotFlags=%d",
__FUNCTION__, args.orientation, args.rotFlags);
return true; return true;
} }
ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__);
OVASSERT(!mMem.prev().valid(), "Prev should not be valid"); OVASSERT(!mMem.prev().valid(), "Prev should not be valid");
// remap and have the current to be the new one.
// ++mMem will make curr to be prev, and prev will be curr // ++mMem will make curr to be prev, and prev will be curr
++mMem; ++mMem;
if(!open_i(numbufs, args.whf.size)) { if(!open_i(numbufs, mBufSize)) {
ALOGE("%s Error could not open", __FUNCTION__); ALOGE("%s Error could not open", __FUNCTION__);
return false; return false;
} }
OVASSERT(numbufs <= ROT_MAX_BUF_OFFSET,
"Numbufs %d > ROT_MAX_BUF_OFFSET", numbufs);
for (uint32_t i = 0; i < numbufs; ++i) { for (uint32_t i = 0; i < numbufs; ++i) {
mMem.curr().mRotOffset[i] = i * args.whf.size; mMem.curr().mRotOffset[i] = i * mBufSize;
} }
return true; return true;
} }
bool MdpRot::start() {
if(!overlay::mdp_wrapper::startRotator(mFd.getFD(), mRotImgInfo)) {
ALOGE("MdpRot start failed");
this->dump();
return false;
}
mRotDataInfo.session_id = mRotImgInfo.session_id;
return true;
}
void MdpRot::reset() { void MdpRot::reset() {
ovutils::memset0(mRotImgInfo); ovutils::memset0(mRotImgInfo);
ovutils::memset0(mRotDataInfo); ovutils::memset0(mRotDataInfo);
ovutils::memset0(mData);
ovutils::memset0(mMem.curr().mRotOffset); ovutils::memset0(mMem.curr().mRotOffset);
ovutils::memset0(mMem.prev().mRotOffset); ovutils::memset0(mMem.prev().mRotOffset);
mMem.curr().mCurrOffset = 0; mMem.curr().mCurrOffset = 0;
mMem.prev().mCurrOffset = 0; mMem.prev().mCurrOffset = 0;
isSrcFB = false; mBufSize = 0;
mOrientation = utils::OVERLAY_TRANSFORM_0;
} }
bool MdpRot::prepareQueueBuf(uint32_t offset) { bool MdpRot::queueBuffer(int fd, uint32_t offset) {
// FIXME if it fails, what happens to the above current item?
if(enabled()) { if(enabled()) {
OVASSERT(mMem.curr().m.numBufs(), mRotDataInfo.src.memory_id = fd;
"prepareQueueBuf numbufs is 0");
// If the rotator source is FB
if(isSrcFB) {
mRotDataInfo.src.flags |= MDP_MEMORY_ID_TYPE_FB;
}
mRotDataInfo.src.offset = offset; mRotDataInfo.src.offset = offset;
remap(RotMem::Mem::ROT_NUM_BUFS);
OVASSERT(mMem.curr().m.numBufs(),
"queueBuffer numbufs is 0");
mRotDataInfo.dst.offset = mRotDataInfo.dst.offset =
mMem.curr().mRotOffset[mMem.curr().mCurrOffset]; mMem.curr().mRotOffset[mMem.curr().mCurrOffset];
mMem.curr().mCurrOffset = mMem.curr().mCurrOffset =
(mMem.curr().mCurrOffset + 1) % mMem.curr().m.numBufs(); (mMem.curr().mCurrOffset + 1) % mMem.curr().m.numBufs();
if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) { if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) {
ALOGE("MdpRot failed rotate"); ALOGE("MdpRot failed rotate");
return false; dump();
}
mData.data.offset = mRotDataInfo.dst.offset;
}
return true;
}
bool MdpRot::play(int fd) {
if(!overlay::mdp_wrapper::play(fd, mData)) {
ALOGE("MdpRot failed to play with fd=%d", fd);
return false; return false;
} }
// if the prev mem is valid, we need to close // if the prev mem is valid, we need to close
if(mMem.prev().valid()) { if(mMem.prev().valid()) {
// FIXME FIXME FIXME if no wait for vsync the above // FIXME if no wait for vsync the above
// play will return immediatly and might cause // play will return immediatly and might cause
// tearing when prev.close is called. // tearing when prev.close is called.
if(!mMem.prev().close()) { if(!mMem.prev().close()) {
ALOGE("%s error in closing prev rot mem", __FUNCTION__); ALOGE("%s error in closing prev rot mem", __FUNCTION__);
return false;
}
} }
} }
return true; return true;
} }
///// Null Rot ////
mdp_overlay NullRotator::setInfo(
const utils::PipeArgs& args,
const mdp_overlay& o) {
return utils::setInfoNullRot(args, o);
}
///// Rotator ////
mdp_overlay Rotator::setInfo(
const utils::PipeArgs& args,
const mdp_overlay& o)
{
return utils::setInfoRot(args, o);
}
bool Rotator::overlayTransform(MdpCtrl& mdp,
utils::eTransform& rot)
{
ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, rot);
switch(int(rot)) {
case 0:
case HAL_TRANSFORM_FLIP_H:
case HAL_TRANSFORM_FLIP_V:
overlayTransFlipHV(mdp, rot);
break;
case HAL_TRANSFORM_ROT_90:
case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
overlayTransFlipRot90(mdp, rot);
break;
case HAL_TRANSFORM_ROT_180:
overlayTransFlipRot180(mdp);
break;
case HAL_TRANSFORM_ROT_270:
overlayTransFlipRot270(mdp);
break;
default:
ALOGE("%s: Error due to unknown rot value %d", __FUNCTION__, rot);
return false;
}
/* everything below is rotation related */
int r = utils::getMdpOrient(rot);
ALOGE_IF(DEBUG_OVERLAY, "%s: r=%d", __FUNCTION__, r);
if (r == -1) {
ALOGE("Ctrl setParameter rot it -1");
return false;
}
// Need to have both in sync
mdp.setUserData(r);
this->setRotations(r);
this->setDisable();
if(r) {
this->setEnable();
}
/* set src format using rotation info
* e.g. (12-->5 in case of rotation) */
mdp.setSrcFormat(this->getSrcWhf());
// based on 90/270 set flags
mdp.setRotationFlags();
return true;
}
void Rotator::overlayTransFlipHV(MdpCtrl& mdp,
utils::eTransform& rot)
{
int val = mdp.getUserData();
ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
utils::Dim d = mdp.getSrcRectDim();
utils::Whf whf = mdp.getSrcWhf();
if (val == MDP_ROT_90) {
int tmp = d.y;
d.y = compute(whf.w,
d.x,
d.w);
d.x = tmp;
mdp.setSrcRectDim(d);
utils::swapOVRotWidthHeight(mRot, mdp);
}
else if (val == MDP_ROT_270) {
int tmp = d.x;
d.x = compute(whf.h,
d.y,
d.h);
d.y = tmp;
mdp.setSrcRectDim(d);
utils::swapOVRotWidthHeight(mRot, mdp);
}
}
void Rotator::overlayTransFlipRot90(MdpCtrl& mdp,
utils::eTransform& rot)
{
int val = mdp.getUserData();
ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
utils::Dim d = mdp.getSrcRectDim();
utils::Whf whf = mdp.getSrcWhf();
if (val == MDP_ROT_270) {
d.x = compute(whf.w,
d.x,
d.w);
d.y = compute(whf.h,
d.y,
d.h);
}
else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
int tmp = d.x;
d.x = compute(whf.h,
d.y,
d.h);
d.y = tmp;
mdp.setSrcRectDim(d);
utils::swapOVRotWidthHeight(mRot, mdp);
}
}
void Rotator::overlayTransFlipRot180(MdpCtrl& mdp)
{
int val = mdp.getUserData();
ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
utils::Dim d = mdp.getSrcRectDim();
utils::Whf whf = mdp.getSrcWhf();
if (val == MDP_ROT_270) {
int tmp = d.y;
d.y = compute(whf.w,
d.x,
d.w);
d.x = tmp;
mdp.setSrcRectDim(d);
utils::swapOVRotWidthHeight(mRot, mdp);
}
else if (val == MDP_ROT_90) {
int tmp = d.x;
d.x = compute(whf.h,
d.y,
d.h);
d.y = tmp;
mdp.setSrcRectDim(d);
utils::swapOVRotWidthHeight(mRot, mdp);
}
}
void Rotator::overlayTransFlipRot270(MdpCtrl& mdp)
{
int val = mdp.getUserData();
ALOGE_IF(DEBUG_OVERLAY, "%s: prev=%d", __FUNCTION__, val);
utils::Dim d = mdp.getSrcRectDim();
utils::Whf whf = mdp.getSrcWhf();
if (val == MDP_ROT_90) {
d.y = compute(whf.h,
d.y,
d.h);
d.x = compute(whf.w,
d.x,
d.w);
}
else if (val == MDP_ROT_NOP || val == MDP_ROT_180) {
int tmp = d.y;
d.y = compute(whf.w,
d.x,
d.w);
d.x = tmp;
mdp.setSrcRectDim(d);
utils::swapOVRotWidthHeight(mRot, mdp);
}
}
void MdpRot::dump() const { void MdpRot::dump() const {
ALOGE("== Dump MdpRot start =="); ALOGE("== Dump MdpRot start ==");
mFd.dump(); mFd.dump();
mMem.curr().m.dump(); mMem.curr().m.dump();
mdp_wrapper::dump("mRotImgInfo", mRotImgInfo); mdp_wrapper::dump("mRotImgInfo", mRotImgInfo);
mdp_wrapper::dump("mRotDataInfo", mRotDataInfo); mdp_wrapper::dump("mRotDataInfo", mRotDataInfo);
mdp_wrapper::dump("mData", mData);
ALOGE("== Dump MdpRot end =="); ALOGE("== Dump MdpRot end ==");
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@@ -27,8 +27,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef OVERLAY_ROTATOR_H #ifndef OVERlAY_ROTATOR_H
#define OVERLAY_ROTATOR_H #define OVERlAY_ROTATOR_H
#include <stdlib.h> #include <stdlib.h>
@@ -37,158 +37,111 @@
#include "overlayMem.h" #include "overlayMem.h"
namespace overlay { namespace overlay {
class MdpCtrl;
class IRotatorHw;
/* /*
* MDP rot holds MDP's rotation related structures. * RotatorBase. No members, just interface.
* * can also be =0 with empty impl in cpp.
* */
class MdpRot {
public:
/* ctor */
explicit MdpRot();
/* open fd for rotator. map bufs is defered */
bool open();
/* remap rot buffers */
bool remap(uint32_t numbufs, const utils::PipeArgs& args);
/* Unmap everything that is not current */
bool unmapNonCurrent();
/* close fd, mem */
bool close();
/* reset underlying data, basically memset 0 */
void reset();
/* calls underlying wrappers to start rotator */
bool start();
/* start underlying but use given whf and flags */
bool start(const utils::PipeArgs& args);
/* start underlying but use given whf and flags.
* Has the ability to parameterize the dst fmt */
template <int ROT_OUT_FMT>
bool start(const utils::PipeArgs& args);
/* assign memory id to mdp structure */
void setDataMemId(int fd);
void setRotDataSrcMemId(int fd);
/* Mark src as FB (non-ION) */
void setSrcFB(bool);
/* get dst (for offset and memory id) non-virt */
int getDstMemId() const;
uint32_t getDstOffset() const;
/* set enable/disable flag */
void setEnable();
void setDisable();
bool enabled() const;
/* set rotator flag*/
void setRotations(uint32_t r);
/* set the req data id in mData */
void setDataReqId(int id);
/* swap rot info dst w/h */
void swapDstWH();
/* returns a copy of src whf */
utils::Whf getSrcWhf() const;
/* setup rotator data before queue buf calls
* call play if rotate call succeed. return false if failed */
bool prepareQueueBuf(uint32_t offset);
/* call play on mdp*/
bool play(int fd);
/* set src whf */
void setSrcWhf(const utils::Whf& whf);
/* returns rotator session id */
int getSessId() const;
/* dump the state of the object */
void dump() const;
private:
bool open_i(uint32_t numbufs, uint32_t bufsz);
/* max buf no for offset */
enum { ROT_MAX_BUF_OFFSET = 2 };
/* rot info*/
msm_rotator_img_info mRotImgInfo;
/* rot data */
msm_rotator_data_info mRotDataInfo;
/* data needed for rotator */
msmfb_overlay_data mData;
/* rotator fd */
OvFD mFd;
/* Array of memory map for rotator
* The array enable us to change rot buffers/mapping
* on the fly*/
struct RotMem {
enum {MAX_ROT_MEM = 2};
struct Mem {
Mem() : mCurrOffset(0) {utils::memset0(mRotOffset); }
bool valid() { return m.valid(); }
bool close() { return m.close(); }
uint32_t size() const { return m.bufSz(); }
/* rotator data info dst offset */
uint32_t mRotOffset[ROT_MAX_BUF_OFFSET];
/* current offset slot from mRotOffset */
uint32_t mCurrOffset;
OvMem m;
};
RotMem() : _curr(0) {}
Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
RotMem& operator++() { ++_curr; return *this; }
bool close();
uint32_t _curr;
Mem m[MAX_ROT_MEM];
} mMem;
bool isSrcFB;
};
/*
* RotatorBase. No memebers, just interface.
* ~ can also be =0 with empty impl in cpp.
* */ * */
class RotatorBase { class RotatorBase {
public: public:
/* Most of the below are No op funcs for RotatorBase */ /* Most of the below are No op funcs for RotatorBase */
virtual ~RotatorBase() {} virtual ~RotatorBase() {}
virtual bool open() = 0; virtual bool init() = 0;
virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args) = 0;
virtual bool close() = 0; virtual bool close() = 0;
virtual bool start(const utils::PipeArgs& args) = 0; virtual void setSource(const utils::Whf& wfh) = 0;
virtual bool start() = 0; virtual void setFlags(const utils::eMdpFlags& flags) = 0;
virtual mdp_overlay setInfo(const utils::PipeArgs& args, virtual void setTransform(const utils::eTransform& rot,
const mdp_overlay& o) = 0; const bool& rotUsed) = 0;
virtual bool overlayTransform(MdpCtrl& mdp, virtual bool commit() = 0;
utils::eTransform& rot) = 0; virtual bool queueBuffer(int fd, uint32_t offset) = 0;
virtual void setSrcWhf(const utils::Whf& wfh) = 0;
virtual utils::Whf getSrcWhf() const = 0;
virtual void setRotations(uint32_t r) = 0;
virtual void setDataReqId(int id) = 0;
virtual bool prepareQueueBuf(uint32_t offset) = 0;
virtual bool play(int fd) = 0;
virtual void setEnable() = 0; virtual void setEnable() = 0;
virtual void setDisable() = 0; virtual void setDisable() = 0;
virtual void setRotations(uint32_t r) = 0;
virtual void setSrcFB() = 0;
virtual bool enabled() const = 0; virtual bool enabled() const = 0;
virtual void setDataMemId(int fd) = 0;
virtual void setRotDataSrcMemId(int fd) = 0;
virtual void setSrcFB(bool) = 0;
virtual int getSessId() const = 0; virtual int getSessId() const = 0;
virtual int getDstMemId() const = 0;
virtual uint32_t getDstOffset() const = 0;
virtual void dump() const = 0; virtual void dump() const = 0;
protected:
//Hardware specific rotator impl.
IRotatorHw *mRot;
};
/*
* Rotator Hw Interface. Any hardware specific implementation should inherit
* from this.
*/
class IRotatorHw {
public:
/* Most of the below are No op funcs for RotatorBase */
virtual ~IRotatorHw() {}
/* init fd for rotator. map bufs is defered */
virtual bool init() = 0;
/* close fd, mem */
virtual bool close() = 0;
/* set src */
virtual void setSource(const utils::Whf& wfh) = 0;
/* set mdp flags, will use only stuff necessary for rotator */
virtual void setFlags(const utils::eMdpFlags& flags) = 0;
/* Set rotation and calculate */
virtual void setTransform(const utils::eTransform& rot,
const bool& rotUsed) = 0;
/* calls underlying wrappers to start rotator */
virtual bool commit() = 0;
/* Lazy buffer allocation. queue buffer */
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
/* set enable/disable flag */
virtual void setEnable() = 0;
virtual void setDisable() = 0;
/* set rotator flag*/
virtual void setRotations(uint32_t r) = 0;
/* Mark src as FB (non-ION) */
virtual void setSrcFB() = 0;
/* Retusn true if rotator enabled */
virtual bool enabled() const = 0;
/* returns rotator session id */
virtual int getSessId() const = 0;
/* get dst (for offset and memory id) non-virt */
virtual int getDstMemId() const = 0;
virtual uint32_t getDstOffset() const = 0;
/* dump the state of the object */
virtual void dump() const = 0;
enum { TYPE_MDP, TYPE_MDSS };
/*Returns rotator h/w type */
static int getRotatorHwType();
};
/*
* Actual Rotator impl.
* */
class Rotator : public RotatorBase
{
public:
explicit Rotator();
virtual ~Rotator();
virtual bool init();
virtual bool close();
virtual void setSource(const utils::Whf& wfh);
virtual void setFlags(const utils::eMdpFlags& flags);
virtual void setTransform(const utils::eTransform& rot,
const bool& rotUsed);
virtual bool commit();
virtual void setRotations(uint32_t r);
virtual void setSrcFB();
virtual int getDstMemId() const;
virtual uint32_t getDstOffset() const;
virtual void setEnable();
virtual void setDisable();
virtual bool enabled () const;
virtual int getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
}; };
/* /*
@@ -198,357 +151,217 @@ class NullRotator : public RotatorBase {
public: public:
/* Most of the below are No op funcs for RotatorBase */ /* Most of the below are No op funcs for RotatorBase */
virtual ~NullRotator(); virtual ~NullRotator();
virtual bool open(); virtual bool init();
virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args);
virtual bool close(); virtual bool close();
virtual bool start(const utils::PipeArgs& args); virtual void setSource(const utils::Whf& wfh);
virtual bool start(); virtual void setFlags(const utils::eMdpFlags& flags);
/* null rotator behavior should set info in a specific way */ virtual void setTransform(const utils::eTransform& rot,
virtual mdp_overlay setInfo(const utils::PipeArgs& args, const bool& rotUsed);
const mdp_overlay& o); virtual bool commit();
virtual bool overlayTransform(MdpCtrl& o,
utils::eTransform& rot);
virtual void setSrcWhf(const utils::Whf& wfh);
virtual utils::Whf getSrcWhf() const;
virtual void setRotations(uint32_t r); virtual void setRotations(uint32_t r);
virtual void setDataReqId(int id); virtual bool queueBuffer(int fd, uint32_t offset);
virtual bool prepareQueueBuf(uint32_t offset);
virtual bool play(int fd);
virtual void setEnable(); virtual void setEnable();
virtual void setDisable(); virtual void setDisable();
virtual bool enabled () const; virtual bool enabled () const;
virtual void setDataMemId(int fd); virtual void setSrcFB();
virtual void setRotDataSrcMemId(int fd);
virtual void setSrcFB(bool);
virtual int getSessId() const; virtual int getSessId() const;
virtual int getDstMemId() const;
virtual uint32_t getDstOffset() const;
virtual void dump() const; virtual void dump() const;
}; };
/*
Manages the case where new rotator memory needs to be
allocated, before previous is freed, due to resolution change etc. If we make
rotator memory to be always max size, irrespctive of source resolution then
we don't need this RotMem wrapper. The inner class is sufficient.
*/
struct RotMem {
// Max rotator memory allocations
enum { MAX_ROT_MEM = 2};
//Manages the rotator buffer offsets.
struct Mem {
Mem() : mCurrOffset(0) {utils::memset0(mRotOffset); }
bool valid() { return m.valid(); }
bool close() { return m.close(); }
uint32_t size() const { return m.bufSz(); }
// Max rotator buffers
enum { ROT_NUM_BUFS = 2 };
// rotator data info dst offset
uint32_t mRotOffset[ROT_NUM_BUFS];
// current offset slot from mRotOffset
uint32_t mCurrOffset;
OvMem m;
};
RotMem() : _curr(0) {}
Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
RotMem& operator++() { ++_curr; return *this; }
bool close();
uint32_t _curr;
Mem m[MAX_ROT_MEM];
};
/* /*
* Rotator impl. * MDP rot holds MDP's rotation related structures.
*
* */ * */
class Rotator : public RotatorBase class MdpRot : public IRotatorHw {
{
public: public:
/* construct underlying object */ explicit MdpRot();
explicit Rotator(); ~MdpRot();
bool init();
/* close underlying rot */ bool close();
virtual ~Rotator(); void setSource(const utils::Whf& whf);
virtual void setFlags(const utils::eMdpFlags& flags);
/* calls underlying open */ void setTransform(const utils::eTransform& rot,
virtual bool open(); const bool& rotUsed);
bool commit();
/* remap rot buffers */ bool queueBuffer(int fd, uint32_t offset);
virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args); void setEnable();
void setDisable();
/* calls underlying close */ void setRotations(uint32_t r);
virtual bool close(); void setSrcFB();
bool enabled() const;
/* calls underlying start */ int getSessId() const;
virtual bool start();
/* calls underlying start with whf and flags */
virtual bool start(const utils::PipeArgs& args);
/* non virtual - calls underlying start with whf and flags.
* Has the ability to parameterize the dst */
template <int ROT_OUT_FMT>
bool start(const utils::PipeArgs& args);
/* Unmap everything that is not current */
bool unmapNonCurrent();
/* set info using whf and given mdp */
virtual mdp_overlay setInfo(const utils::PipeArgs& args,
const mdp_overlay& o);
/* transform function for the MDP */
virtual bool overlayTransform(MdpCtrl& mdp,
utils::eTransform& rot);
/* set src whf */
virtual void setSrcWhf(const utils::Whf& wfh);
/* set Rotations */
virtual void setRotations(uint32_t r);
/* set the req data id in mData */
virtual void setDataReqId(int id);
/* set memory_id */
virtual void setDataMemId(int fd);
virtual void setRotDataSrcMemId(int fd);
/* Mark the src for rotator as FB. usually set by UI mirroing cases */
virtual void setSrcFB(bool);
/* get dst (for offset and memory id) non-virt */
int getDstMemId() const; int getDstMemId() const;
uint32_t getDstOffset() const; uint32_t getDstOffset() const;
void dump() const;
/* set enable/disable flag */
virtual void setEnable();
virtual void setDisable();
virtual bool enabled () const;
/* return rotator sess id */
virtual int getSessId() const;
/* return a copy of src whf*/
virtual utils::Whf getSrcWhf() const;
/* prepare rot for queue buf*/
virtual bool prepareQueueBuf(uint32_t offset);
/* call play on mdp*/
virtual bool play(int fd);
/* dump the state of the object */
virtual void dump() const;
private: private:
/* helper functions for overlayTransform */ /* remap rot buffers */
void overlayTransFlipHV(MdpCtrl& mdp, bool remap(uint32_t numbufs);
utils::eTransform& rot); bool open_i(uint32_t numbufs, uint32_t bufsz);
void overlayTransFlipRot90(MdpCtrl& mdp, /* Deferred transform calculations */
utils::eTransform& rot); void doTransform();
void overlayTransFlipRot180(MdpCtrl& mdp); /* reset underlying data, basically memset 0 */
void overlayTransFlipRot270(MdpCtrl& mdp); void reset();
/* underlying rotator MDP object */ /* rot info*/
MdpRot mRot; msm_rotator_img_info mRotImgInfo;
/* rot data */
msm_rotator_data_info mRotDataInfo;
/* Orientation */
utils::eTransform mOrientation;
/* rotator fd */
OvFD mFd;
/* Rotator memory manager */
RotMem mMem;
/* Single Rotator buffer size */
uint32_t mBufSize;
}; };
//--------------inlines------------------------------------ //--------------inlines------------------------------------
//// MdpRot ////
inline MdpRot::MdpRot() { reset(); } ///// Rotator /////
inline bool MdpRot::start(const utils::PipeArgs& args) { inline Rotator::Rotator() {
return this->start<utils::ROT_OUT_FMT_DEFAULT>(args); int type = IRotatorHw::getRotatorHwType();
if(type == IRotatorHw::TYPE_MDP) {
mRot = new MdpRot(); //will do reset
} else if(type == IRotatorHw::TYPE_MDSS) {
//TODO create mdss specific rotator
} else {
ALOGE("%s Unknown h/w type %d", __FUNCTION__, type);
}
}
inline Rotator::~Rotator() {
delete mRot; //will do close
}
inline bool Rotator::init() {
if(!mRot->init()) {
ALOGE("Rotator::init failed");
return false;
}
return true;
}
inline bool Rotator::close() {
return mRot->close();
}
inline void Rotator::setSource(const utils::Whf& whf) {
mRot->setSource(whf);
}
inline void Rotator::setFlags(const utils::eMdpFlags& flags) {
mRot->setFlags(flags);
}
inline void Rotator::setTransform(const utils::eTransform& rot,
const bool& rotUsed)
{
mRot->setTransform(rot, rotUsed);
}
inline bool Rotator::commit() {
return mRot->commit();
}
inline void Rotator::setEnable(){ mRot->setEnable(); }
inline void Rotator::setDisable(){ mRot->setDisable(); }
inline bool Rotator::enabled() const { return mRot->enabled(); }
inline void Rotator::setSrcFB() { mRot->setSrcFB(); }
inline int Rotator::getDstMemId() const {
return mRot->getDstMemId();
}
inline uint32_t Rotator::getDstOffset() const {
return mRot->getDstOffset();
}
inline void Rotator::setRotations(uint32_t rot) {
mRot->setRotations (rot);
}
inline int Rotator::getSessId() const {
return mRot->getSessId();
}
inline void Rotator::dump() const {
ALOGE("== Dump Rotator start ==");
mRot->dump();
ALOGE("== Dump Rotator end ==");
}
inline bool Rotator::queueBuffer(int fd, uint32_t offset) {
return mRot->queueBuffer(fd, offset);
} }
inline void MdpRot::setDataMemId(int fd) { mData.data.memory_id = fd; }
inline void MdpRot::setRotDataSrcMemId(int fd) {
mRotDataInfo.src.memory_id = fd; }
///// Null Rotator /////
inline NullRotator::~NullRotator() {}
inline bool NullRotator::init() { return true; }
inline bool NullRotator::close() { return true; }
inline bool NullRotator::commit() { return true; }
inline void NullRotator::setSource(const utils::Whf& wfh) {}
inline void NullRotator::setFlags(const utils::eMdpFlags& flags) {}
inline void NullRotator::setTransform(const utils::eTransform& rot, const bool&)
{}
inline void NullRotator::setRotations(uint32_t) {}
inline void NullRotator::setEnable() {}
inline void NullRotator::setDisable() {}
inline bool NullRotator::enabled() const { return false; }
inline int NullRotator::getSessId() const { return -1; }
inline bool NullRotator::queueBuffer(int fd, uint32_t offset) { return true; }
inline void NullRotator::setSrcFB() {}
inline int NullRotator::getDstMemId() const { return -1; }
inline uint32_t NullRotator::getDstOffset() const { return 0;}
inline void NullRotator::dump() const {
ALOGE("== Dump NullRotator dump (null) start/end ==");
}
//// MdpRot ////
inline MdpRot::MdpRot() { reset(); }
inline MdpRot::~MdpRot() { close(); }
inline void MdpRot::setEnable() { mRotImgInfo.enable = 1; } inline void MdpRot::setEnable() { mRotImgInfo.enable = 1; }
inline void MdpRot::setDisable() { mRotImgInfo.enable = 0; } inline void MdpRot::setDisable() { mRotImgInfo.enable = 0; }
inline bool MdpRot::enabled() const { return mRotImgInfo.enable; } inline bool MdpRot::enabled() const { return mRotImgInfo.enable; }
inline void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; } inline void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; }
inline void MdpRot::setDataReqId(int id) { mData.id = id; }
inline void MdpRot::swapDstWH() {
overlay::utils::swap(mRotImgInfo.dst.width,
mRotImgInfo.dst.height); }
inline overlay::utils::Whf MdpRot::getSrcWhf() const {
return overlay::utils::Whf(mRotImgInfo.src.width,
mRotImgInfo.src.height,
mRotImgInfo.src.format);
}
inline int MdpRot::getDstMemId() const { inline int MdpRot::getDstMemId() const {
return mRotDataInfo.dst.memory_id; return mRotDataInfo.dst.memory_id;
} }
inline uint32_t MdpRot::getDstOffset() const { inline uint32_t MdpRot::getDstOffset() const {
return mRotDataInfo.dst.offset; return mRotDataInfo.dst.offset;
} }
inline void MdpRot::setSrcWhf(const overlay::utils::Whf& whf) {
mRotImgInfo.src.width = whf.w;
mRotImgInfo.src.height = whf.h;
mRotImgInfo.src.format = whf.format;
}
inline int MdpRot::getSessId() const { return mRotImgInfo.session_id; } inline int MdpRot::getSessId() const { return mRotImgInfo.session_id; }
inline void MdpRot::setSrcFB() {
inline void MdpRot::setSrcFB(bool mark) { isSrcFB = mark; } mRotDataInfo.src.flags |= MDP_MEMORY_ID_TYPE_FB;
///// Null Rotator /////
inline NullRotator::~NullRotator() {}
inline bool NullRotator::open() {
return true; }
inline bool NullRotator::remap(uint32_t numbufs,
const utils::PipeArgs& args){
return true; }
inline bool NullRotator::close() { return true; }
inline bool NullRotator::start(const utils::PipeArgs& args)
{ return true; }
inline bool NullRotator::start() { return true; }
inline bool NullRotator::overlayTransform(MdpCtrl& o,
utils::eTransform& rot)
{ return true; }
inline void NullRotator::setSrcWhf(const overlay::utils::Whf& wfh) {}
inline void NullRotator::setRotations(uint32_t) {}
inline void NullRotator::setDataReqId(int id) {}
inline void NullRotator::setEnable() {}
inline void NullRotator::setDisable() {}
inline bool NullRotator::enabled() const { return false; }
inline int NullRotator::getSessId() const { return -1; }
inline overlay::utils::Whf NullRotator::getSrcWhf() const {
return overlay::utils::Whf(); }
inline bool NullRotator::prepareQueueBuf(uint32_t offset)
{ return true; }
inline bool NullRotator::play(int fd)
{ return true; }
inline void NullRotator::setDataMemId(int fd) {}
inline void NullRotator::setRotDataSrcMemId(int fd) {}
inline void NullRotator::setSrcFB(bool) {}
inline void NullRotator::dump() const {
ALOGE("== Dump NullRotator dump (null) start/end ==");
}
///// Rotator /////
inline Rotator::Rotator() { }
inline Rotator::~Rotator() {
mRot.close(); // also will do reset
}
inline bool Rotator::open() {
if(!mRot.open()) {
ALOGE("Rotator::open failed");
return false;
}
return true;
}
template <int ROT_OUT_FMT>
inline bool Rotator::start(const utils::PipeArgs& args) {
return mRot.start<ROT_OUT_FMT>(args);
}
inline bool Rotator::remap(uint32_t numbufs,
const utils::PipeArgs& args){
if(!mRot.remap(numbufs, args)) {
ALOGE("%s failed", __FUNCTION__);
return false;
}
return true;
}
inline bool Rotator::close() {
return mRot.close();
}
inline bool Rotator::start() {
return mRot.start();
}
inline bool Rotator::start(const utils::PipeArgs& args) {
return mRot.start(args);
}
inline bool Rotator::unmapNonCurrent() {
return mRot.unmapNonCurrent();
}
inline void Rotator::setEnable(){ mRot.setEnable(); }
inline void Rotator::setDisable(){ mRot.setDisable(); }
inline bool Rotator::enabled() const { return mRot.enabled(); }
inline void Rotator::setDataMemId(int fd) {
mRot.setDataMemId(fd); }
inline void Rotator::setRotDataSrcMemId(int fd) {
mRot.setRotDataSrcMemId(fd);
}
inline void Rotator::setSrcFB(bool mark) { mRot.setSrcFB(mark); }
inline int Rotator::getDstMemId() const {
return mRot.getDstMemId();
}
inline uint32_t Rotator::getDstOffset() const {
return mRot.getDstOffset();
}
inline void Rotator::setDataReqId(int id) {
mRot.setDataReqId(id);
}
inline void Rotator::setSrcWhf(
const overlay::utils::Whf& whf) {
mRot.setSrcWhf(whf);
}
inline void Rotator::setRotations(uint32_t rot) {
mRot.setRotations (rot);
}
inline int Rotator::getSessId() const {
return mRot.getSessId(); }
inline void Rotator::dump() const {
ALOGE("== Dump Rotator start ==");
mRot.dump();
ALOGE("== Dump Rotator end ==");
}
inline overlay::utils::Whf Rotator::getSrcWhf() const {
return mRot.getSrcWhf(); }
inline bool Rotator::prepareQueueBuf(uint32_t offset)
{
return mRot.prepareQueueBuf(offset);
}
inline bool Rotator::play(int fd)
{
return mRot.play(fd);
}
template <int ROT_OUT_FMT>
bool MdpRot::start(const utils::PipeArgs& args) {
// Do nothing when no orientation
if(utils::OVERLAY_TRANSFORM_0 == args.orientation &&
utils::ROT_FLAG_ENABLED != args.rotFlags) {
return true;
}
utils::Whf whf(args.whf);
mRotImgInfo.src.format = whf.format;
mRotImgInfo.src.width = whf.w;
mRotImgInfo.src.height = whf.h;
mRotImgInfo.src_rect.w = whf.w;
mRotImgInfo.src_rect.h = whf.h;
mRotImgInfo.dst.width = whf.w;
mRotImgInfo.dst.height = whf.h;
if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
whf.format == MDP_Y_CBCR_H2V2_TILE) {
mRotImgInfo.src.width = utils::alignup(whf.w, 64);
mRotImgInfo.src.height = utils::alignup(whf.h, 32);
mRotImgInfo.src_rect.w = utils::alignup(whf.w, 64);
mRotImgInfo.src_rect.h = utils::alignup(whf.h, 32);
mRotImgInfo.dst.width = utils::alignup(whf.w, 64);
mRotImgInfo.dst.height = utils::alignup(whf.h, 32);
mRotImgInfo.dst.format = MDP_Y_CRCB_H2V2;
}
// either utils::getRotOutFmt(whf.format); or supplied fmt
// utils::RotOutFmt<ROT_OUT_FMT_DEFAULT>::fmt;
mRotImgInfo.dst.format = utils::RotOutFmt<ROT_OUT_FMT>::fmt(whf.format);
mRotImgInfo.dst_x = 0;
mRotImgInfo.dst_y = 0;
mRotImgInfo.src_rect.x = 0;
mRotImgInfo.src_rect.y = 0;
mRotImgInfo.rotations = 0;
// ROT_FLAG_DISABLED / ENABLED
// Refer to overlayUtils.h eRotFlags
// for more info
mRotImgInfo.enable = args.rotFlags;
mRotImgInfo.session_id = mRotImgInfo.session_id ?
mRotImgInfo.session_id : 0;
return start();
} }
} // overlay } // overlay
namespace { #endif // OVERlAY_ROTATOR_H
// just a helper func for Rotator common operations x-(y+z)
int compute(uint32_t x, uint32_t y, uint32_t z) {
return x-(y+z);
}
}
#endif // OVERLAY_ROTATOR_H

View File

@@ -34,22 +34,16 @@
#include "overlayImpl.h" #include "overlayImpl.h"
#include "overlayRotator.h" #include "overlayRotator.h"
#include "pipes/overlayGenPipe.h" #include "pipes/overlayGenPipe.h"
#include "pipes/overlayBypassPipe.h" #include "pipes/overlayVideoExtPipe.h"
#include "pipes/overlayHdmiPipe.h"
#include "pipes/overlayUIMirrorPipe.h" #include "pipes/overlayUIMirrorPipe.h"
#include "pipes/overlay3DPipe.h" #include "pipes/overlay3DPipe.h"
// FIXME make int to be uint32 whenever possible
namespace overlay { namespace overlay {
/* /*
* Used by Overlay class. Invokes each event * Used by Overlay class. Invokes each event
* */ * */
/* TODO case of RGBx will call mOv open with diff
* params customized for RGBx pipes */
class OverlayState : utils::NoCopy { class OverlayState : utils::NoCopy {
public: public:
/**/ /**/
@@ -153,11 +147,11 @@ template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL>
template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV> template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV>
{ {
typedef overlay::GenericPipe<utils::PRIMARY> pipe0; typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
typedef overlay::HdmiPipe pipe1; typedef overlay::VideoExtPipe pipe1;
typedef overlay::NullPipe pipe2; // place holder typedef overlay::NullPipe pipe2; // place holder
typedef Rotator rot0; typedef Rotator rot0;
typedef NullRotator rot1; typedef Rotator rot1;
typedef NullRotator rot2; typedef NullRotator rot2;
typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl; typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl;
@@ -231,11 +225,11 @@ template <> struct StateTraits<utils::OV_UI_MIRROR>
template <> struct StateTraits<utils::OV_2D_TRUE_UI_MIRROR> template <> struct StateTraits<utils::OV_2D_TRUE_UI_MIRROR>
{ {
typedef overlay::GenericPipe<utils::PRIMARY> pipe0; typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
typedef overlay::HdmiPipe pipe1; typedef overlay::VideoExtPipe pipe1;
typedef overlay::UIMirrorPipe pipe2; typedef overlay::UIMirrorPipe pipe2;
typedef Rotator rot0; typedef Rotator rot0;
typedef NullRotator rot1; typedef Rotator rot1;
typedef Rotator rot2; typedef Rotator rot2;
typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl;
@@ -243,7 +237,7 @@ template <> struct StateTraits<utils::OV_2D_TRUE_UI_MIRROR>
template <> struct StateTraits<utils::OV_BYPASS_1_LAYER> template <> struct StateTraits<utils::OV_BYPASS_1_LAYER>
{ {
typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_SET, utils::WAIT, utils::ZORDER_0> pipe0; typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
typedef overlay::NullPipe pipe1; // place holder typedef overlay::NullPipe pipe1; // place holder
typedef overlay::NullPipe pipe2; // place holder typedef overlay::NullPipe pipe2; // place holder
@@ -256,8 +250,8 @@ template <> struct StateTraits<utils::OV_BYPASS_1_LAYER>
template <> struct StateTraits<utils::OV_BYPASS_2_LAYER> template <> struct StateTraits<utils::OV_BYPASS_2_LAYER>
{ {
typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_SET, utils::NO_WAIT, utils::ZORDER_0> pipe0; typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_OFF, utils::WAIT, utils::ZORDER_1> pipe1; typedef overlay::GenericPipe<utils::PRIMARY> pipe1;
typedef overlay::NullPipe pipe2; // place holder typedef overlay::NullPipe pipe2; // place holder
typedef NullRotator rot0; typedef NullRotator rot0;
@@ -269,9 +263,9 @@ template <> struct StateTraits<utils::OV_BYPASS_2_LAYER>
template <> struct StateTraits<utils::OV_BYPASS_3_LAYER> template <> struct StateTraits<utils::OV_BYPASS_3_LAYER>
{ {
typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_SET, utils::NO_WAIT, utils::ZORDER_0> pipe0; typedef overlay::GenericPipe<utils::PRIMARY> pipe0;
typedef overlay::BypassPipe<utils::OV_MDP_PIPE_VG, utils::IS_FG_OFF, utils::NO_WAIT, utils::ZORDER_1> pipe1; typedef overlay::GenericPipe<utils::PRIMARY> pipe1;
typedef overlay::BypassPipe<utils::OV_MDP_PIPE_RGB, utils::IS_FG_OFF, utils::WAIT, utils::ZORDER_2> pipe2; typedef overlay::GenericPipe<utils::PRIMARY> pipe2;
typedef NullRotator rot0; typedef NullRotator rot0;
typedef NullRotator rot1; typedef NullRotator rot1;
@@ -310,8 +304,8 @@ inline OverlayImplBase* handle_closed_to_xxx()
RotatorBase* rot0 = new typename StateTraits<STATE>::rot0; RotatorBase* rot0 = new typename StateTraits<STATE>::rot0;
RotatorBase* rot1 = new typename StateTraits<STATE>::rot1; RotatorBase* rot1 = new typename StateTraits<STATE>::rot1;
RotatorBase* rot2 = new typename StateTraits<STATE>::rot2; RotatorBase* rot2 = new typename StateTraits<STATE>::rot2;
if(!ov->open(rot0, rot1, rot2)) { if(!ov->init(rot0, rot1, rot2)) {
ALOGE("Overlay failed to open in state %d", STATE); ALOGE("Overlay failed to init in state %d", STATE);
return 0; return 0;
} }
return ov; return ov;
@@ -329,7 +323,7 @@ inline OverlayImplBase* handle_xxx_to_closed(OverlayImplBase* ov)
return 0; return 0;
} }
/* Hard transitions from any state to any state will close and then open */ /* Hard transitions from any state to any state will close and then init */
template <int STATE> template <int STATE>
inline OverlayImplBase* handle_xxx_to_xxx(OverlayImplBase* ov) inline OverlayImplBase* handle_xxx_to_xxx(OverlayImplBase* ov)
{ {
@@ -392,6 +386,7 @@ inline OverlayImplBase* OverlayState::handleEvent(utils::eOverlayState newState,
// FIXME, how to communicate bad transition? // FIXME, how to communicate bad transition?
// Should we have bool returned from transition func? // Should we have bool returned from transition func?
// This is also a very good interview question.
return newov; return newov;
} }

View File

@@ -42,12 +42,12 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DPanel(
// Create new ovimpl based on new state // Create new ovimpl based on new state
typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL> NewState; typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL> NewState;
OverlayImplBase* newov = new NewState::ovimpl; OverlayImplBase* newov = new NewState::ovimpl();
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (GenericPipe) // pipe0/rot0 (GenericPipe)
@@ -55,10 +55,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DPanel(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (GenericPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (GenericPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); RotatorBase* rot0 = new NewState::rot0;
newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (NullPipe) // pipe1/rot1 (NullPipe)
@@ -66,10 +66,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DPanel(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (NullPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); RotatorBase* rot1 = new NewState::rot1;
newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (NullPipe) // pipe2/rot2 (NullPipe)
@@ -77,10 +77,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DPanel(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); RotatorBase* rot2 = new NewState::rot2;
newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -106,7 +106,7 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DTV(
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (GenericPipe) // pipe0/rot0 (GenericPipe)
@@ -114,21 +114,21 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DTV(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (GenericPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (GenericPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (HdmiPipe) // pipe1/rot1 (VideoExtPipe)
if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_HDMI) { if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_VIDEO_EXT) {
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (HdmiPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (VideoExtPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (HdmiPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (VideoExtPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (NullPipe) // pipe2/rot2 (NullPipe)
@@ -136,10 +136,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_2DTV(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -162,21 +162,22 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DPanel(
typedef StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL> NewState; typedef StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL> NewState;
OverlayImplBase* newov = new NewState::ovimpl; OverlayImplBase* newov = new NewState::ovimpl;
//=========================================================== //=================================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl.
// - Otherwise open for new and delete from previous ovimpl // (which also makes previous pipe ref 0, so nobody can use)
//=========================================================== // - Otherwise init pipe for new ovimpl and delete from previous
//=================================================================
// pipe0/rot0 (M3DPrimaryPipe) // pipe0/rot0 (M3DPrimaryPipe)
if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_M3D_PRIMARY) { if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_M3D_PRIMARY) {
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (M3DPrimaryPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (M3DPrimaryPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (NullPipe) // pipe1/rot1 (NullPipe)
@@ -184,10 +185,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DPanel(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (NullPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (NullPipe) // pipe2/rot2 (NullPipe)
@@ -195,10 +196,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DPanel(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -224,7 +225,7 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DTV(
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (M3DPrimaryPipe) // pipe0/rot0 (M3DPrimaryPipe)
@@ -232,10 +233,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DTV(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (M3DPrimaryPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (M3DPrimaryPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (M3DExtPipe) // pipe1/rot1 (M3DExtPipe)
@@ -243,10 +244,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DTV(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (M3DExtPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (M3DExtPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (M3DExtPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (M3DExtPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (NullPipe) // pipe2/rot2 (NullPipe)
@@ -254,10 +255,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_3D_2DTV(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -283,7 +284,7 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_trueUI_Mirror(
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (GenericPipe) // pipe0/rot0 (GenericPipe)
@@ -291,21 +292,21 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_trueUI_Mirror(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (GenericPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (GenericPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (HdmiPipe) // pipe1/rot1 (VideoExtPipe)
if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_HDMI) { if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_VIDEO_EXT) {
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (HdmiPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (VideoExtPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (HdmiPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (VideoExtPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (UIMirrorPipe) // pipe2/rot2 (UIMirrorPipe)
@@ -313,10 +314,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_2D_trueUI_Mirror(
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (UIMirrorPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (UIMirrorPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (UIMirrorPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (UIMirrorPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -341,7 +342,7 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass1(OverlayImplBase* ov)
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (BypassPipe) // pipe0/rot0 (BypassPipe)
@@ -349,10 +350,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass1(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (BypassPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (NullPipe) // pipe1/rot1 (NullPipe)
@@ -360,10 +361,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass1(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (NullPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (NullPipe) // pipe2/rot2 (NullPipe)
@@ -371,10 +372,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass1(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -399,7 +400,7 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass2(OverlayImplBase* ov)
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (BypassPipe) // pipe0/rot0 (BypassPipe)
@@ -407,10 +408,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass2(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (BypassPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (BypassPipe) // pipe1/rot1 (BypassPipe)
@@ -418,10 +419,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass2(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (BypassPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (NullPipe) // pipe2/rot2 (NullPipe)
@@ -429,10 +430,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass2(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (NullPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl
@@ -457,7 +458,7 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass3(OverlayImplBase* ov)
//=========================================================== //===========================================================
// For each pipe: // For each pipe:
// - If pipe matches, copy from previous into new ovimpl // - If pipe matches, copy from previous into new ovimpl
// - Otherwise open for new and delete from previous ovimpl // - Otherwise init for new and delete from previous ovimpl
//=========================================================== //===========================================================
// pipe0/rot0 (BypassPipe) // pipe0/rot0 (BypassPipe)
@@ -465,10 +466,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass3(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE0); newov->copyOvPipe(ov, utils::OV_PIPE0);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe0 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (BypassPipe)", __FUNCTION__);
RotatorBase* rot0 = new NewState::rot0; RotatorBase* rot0 = new NewState::rot0;
ov->closePipe(utils::OV_PIPE0); ov->closePipe(utils::OV_PIPE0);
newov->openPipe(rot0, utils::OV_PIPE0); newov->initPipe(rot0, utils::OV_PIPE0);
} }
// pipe1/rot1 (BypassPipe) // pipe1/rot1 (BypassPipe)
@@ -476,10 +477,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass3(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE1); newov->copyOvPipe(ov, utils::OV_PIPE1);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe1 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (BypassPipe)", __FUNCTION__);
RotatorBase* rot1 = new NewState::rot1; RotatorBase* rot1 = new NewState::rot1;
ov->closePipe(utils::OV_PIPE1); ov->closePipe(utils::OV_PIPE1);
newov->openPipe(rot1, utils::OV_PIPE1); newov->initPipe(rot1, utils::OV_PIPE1);
} }
// pipe2/rot2 (BypassPipe) // pipe2/rot2 (BypassPipe)
@@ -487,10 +488,10 @@ OverlayImplBase* OverlayState::handle_xxx_to_bypass3(OverlayImplBase* ov)
ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (BypassPipe)", __FUNCTION__);
newov->copyOvPipe(ov, utils::OV_PIPE2); newov->copyOvPipe(ov, utils::OV_PIPE2);
} else { } else {
ALOGE_IF(DEBUG_OVERLAY, "%s: Open pipe2 (BypassPipe)", __FUNCTION__); ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (BypassPipe)", __FUNCTION__);
RotatorBase* rot2 = new NewState::rot2; RotatorBase* rot2 = new NewState::rot2;
ov->closePipe(utils::OV_PIPE2); ov->closePipe(utils::OV_PIPE2);
newov->openPipe(rot2, utils::OV_PIPE2); newov->initPipe(rot2, utils::OV_PIPE2);
} }
// All pipes are copied or deleted so no more need for previous ovimpl // All pipes are copied or deleted so no more need for previous ovimpl

View File

@@ -70,7 +70,7 @@ struct IOFile {
namespace overlay { namespace overlay {
//----------From class Res ------------------------------ //----------From class Res ------------------------------
const char* const Res::devTemplate = "/dev/graphics/fb%u"; const char* const Res::fbPath = "/dev/graphics/fb%u";
const char* const Res::rotPath = "/dev/msm_rotator"; const char* const Res::rotPath = "/dev/msm_rotator";
const char* const Res::format3DFile = const char* const Res::format3DFile =
"/sys/class/graphics/fb1/format_3d"; "/sys/class/graphics/fb1/format_3d";
@@ -92,7 +92,7 @@ FrameBufferInfo::FrameBufferInfo() {
OvFD mFd; OvFD mFd;
// Use open defined in overlayFD file to open fd for fb0 // Use open defined in overlayFD file to open fd for fb0
if(!overlay::open(mFd, 0, Res::devTemplate)) { if(!overlay::open(mFd, 0, Res::fbPath)) {
ALOGE("FrameBufferInfo: failed to open fd"); ALOGE("FrameBufferInfo: failed to open fd");
return; return;
} }
@@ -146,41 +146,6 @@ bool FrameBufferInfo::supportTrueMirroring() const {
} }
//-------------------------------------------------------- //--------------------------------------------------------
uint32_t getSize(const Whf& whf) {
int aligned_height=0, pitch=0;
uint32_t size = whf.w * whf.h;
switch (whf.format) {
case MDP_RGBA_8888:
case MDP_BGRA_8888:
case MDP_RGBX_8888:
size *= 4;
break;
case MDP_RGB_565:
case MDP_Y_CBCR_H2V1:
size *= 2;
break;
case MDP_Y_CBCR_H2V2:
case MDP_Y_CRCB_H2V2:
size = (size * 3) / 2;
break;
case MDP_Y_CRCB_H2V2_TILE:
case MDP_Y_CBCR_H2V2_TILE:
aligned_height = align(whf.h , 32);
pitch = align(whf.w, 128);
size = pitch * aligned_height;
size = align(size, 8192);
aligned_height = align(whf.h >> 1, 32);
size += pitch * aligned_height;
size = align(size, 8192);
break;
default:
ALOGE("getSize unknown format %d", whf.format);
return 0;
}
return size;
}
int getMdpFormat(int format) { int getMdpFormat(int format) {
switch (format) { switch (format) {
@@ -205,18 +170,25 @@ int getMdpFormat(int format) {
case HAL_PIXEL_FORMAT_YV12: case HAL_PIXEL_FORMAT_YV12:
return MDP_Y_CR_CB_H2V2; return MDP_Y_CR_CB_H2V2;
default: default:
ALOGE("Error getMdpFormat format=%d", format); ALOGE("Error getMdpFormat format=0x%x", format);
return -1; return -1;
} }
// not reached // not reached
return -1; return -1;
} }
bool isHDMIConnected () { //Set by client as HDMI/WFD
char value[PROPERTY_VALUE_MAX] = {0}; void setExtType(const int& type) {
property_get("hw.hdmiON", value, "0"); if(type != HDMI && type != WFD) {
int isHDMI = atoi(value); ALOGE("%s: Unrecognized type %d", __func__, type);
return isHDMI ? true : false; return;
}
sExtType = type;
}
//Return External panel type set by client.
int getExtType() {
return sExtType;
} }
bool is3DTV() { bool is3DTV() {
@@ -229,7 +201,7 @@ bool is3DTV() {
bool isPanel3D() { bool isPanel3D() {
OvFD fd; OvFD fd;
if(!overlay::open(fd, 0 /*fb*/, Res::devTemplate)){ if(!overlay::open(fd, 0 /*fb*/, Res::fbPath)){
ALOGE("isPanel3D Can't open framebuffer 0"); ALOGE("isPanel3D Can't open framebuffer 0");
return false; return false;
} }
@@ -299,39 +271,6 @@ uint32_t getS3DFormat(uint32_t fmt) {
return fmt3D; return fmt3D;
} }
void normalizeCrop(uint32_t& xy, uint32_t& wh) {
if (xy & 0x0001) {
// x or y is odd, increment it's value
xy += 1;
// Since we've incremented x(y), we need to decrement
// w(h) accordingly
if (wh & 0x0001) {
// w or h is odd, decrement it by 1, to make it even
even_out(wh);
} else {
// w(h) is already even, hence we decrement by 2
wh -=2;
}
} else {
even_out(wh);
}
}
void scale(mdp_overlay& ov)
{
/* Scaling of upto a max of 8 times supported */
overlay::utils::Dim dst(overlay::utils::getDstRectDim(ov));
overlay::utils::Dim src(overlay::utils::getSrcRectDim(ov));
if(dst.w >(src.w * overlay::utils::HW_OV_MAGNIFICATION_LIMIT)) {
dst.w = overlay::utils::HW_OV_MAGNIFICATION_LIMIT * src.w;
}
if(dst.h >(src.h * overlay::utils::HW_OV_MAGNIFICATION_LIMIT)) {
dst.h = overlay::utils::HW_OV_MAGNIFICATION_LIMIT * src.h;
}
setDstRectDim(dst, ov);
}
} // utils } // utils
} // overlay } // overlay

View File

@@ -35,14 +35,14 @@
#include <fcntl.h> // open, O_RDWR, etc #include <fcntl.h> // open, O_RDWR, etc
#include <hardware/hardware.h> #include <hardware/hardware.h>
#include <hardware/gralloc.h> // buffer_handle_t #include <hardware/gralloc.h> // buffer_handle_t
#include <linux/msm_mdp.h> // MDP_OV_PLAY_NOWAIT etc ... #include <linux/msm_mdp.h> // flags
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <utils/Log.h> #include <utils/Log.h>
#include "gralloc_priv.h" //for interlace
/* /*
* *
* Collection of utilities functions/structs/enums etc... * Collection of utilities functions/structs/enums etc...
@@ -70,12 +70,6 @@ class Overlay;
namespace utils { namespace utils {
struct Whf; struct Whf;
struct Dim; struct Dim;
template <class T>
inline void even_out(T& x) { if (x & 0x0001) --x; }
inline uint32_t getBit(uint32_t x, uint32_t mask) {
return (x & mask);
}
inline uint32_t setBit(uint32_t x, uint32_t mask) { inline uint32_t setBit(uint32_t x, uint32_t mask) {
return (x | mask); return (x | mask);
@@ -89,7 +83,7 @@ inline uint32_t clrBit(uint32_t x, uint32_t mask) {
* and assignment operator private * and assignment operator private
* *
* Usage: * Usage:
* * class SomeClass : utils::NoCopy {...}; * class SomeClass : utils::NoCopy {...};
*/ */
class NoCopy { class NoCopy {
protected: protected:
@@ -147,7 +141,14 @@ enum { BARRIER_LAND = 1,
BARRIER_PORT = 2 }; BARRIER_PORT = 2 };
inline uint32_t format3D(uint32_t x) { return x & 0xFF000; } inline uint32_t format3D(uint32_t x) { return x & 0xFF000; }
inline uint32_t colorFormat(uint32_t x) { return x & 0xFFF; } inline uint32_t colorFormat(uint32_t fmt) {
/*TODO enable this block only if format has interlace / 3D info in top bits.
if(fmt & INTERLACE_MASK) {
fmt = fmt ^ HAL_PIXEL_FORMAT_INTERLACE;
}
fmt = fmt & 0xFFF;*/
return fmt;
}
inline uint32_t format3DOutput(uint32_t x) { inline uint32_t format3DOutput(uint32_t x) {
return (x & 0xF000) >> SHIFT_OUT_3D; } return (x & 0xF000) >> SHIFT_OUT_3D; }
inline uint32_t format3DInput(uint32_t x) { return x & 0xF0000; } inline uint32_t format3DInput(uint32_t x) { return x & 0xF0000; }
@@ -160,12 +161,15 @@ bool usePanel3D();
bool send3DInfoPacket (uint32_t fmt); bool send3DInfoPacket (uint32_t fmt);
bool enableBarrier (uint32_t orientation); bool enableBarrier (uint32_t orientation);
uint32_t getS3DFormat(uint32_t fmt); uint32_t getS3DFormat(uint32_t fmt);
template <int CHAN> template <int CHAN>
bool getPositionS3D(const Whf& whf, Dim& out); bool getPositionS3D(const Whf& whf, Dim& out);
template <int CHAN> template <int CHAN>
bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt); bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt);
template <class Type> template <class Type>
void swapWidthHeight(Type& width, Type& height); void swapWidthHeight(Type& width, Type& height);
struct Dim { struct Dim {
Dim () : x(0), y(0), Dim () : x(0), y(0),
@@ -193,13 +197,6 @@ struct Dim {
return !operator==(d); return !operator==(d);
} }
void even_out() {
utils::even_out(x);
utils::even_out(y);
utils::even_out(w);
utils::even_out(h);
}
void dump() const; void dump() const;
uint32_t x; uint32_t x;
uint32_t y; uint32_t y;
@@ -227,26 +224,12 @@ struct Whf {
void dump() const; void dump() const;
uint32_t w; uint32_t w;
uint32_t h; uint32_t h;
// FIXME need to be int32_t ?
uint32_t format; uint32_t format;
uint32_t size; uint32_t size;
}; };
enum { MAX_PATH_LEN = 256 }; enum { MAX_PATH_LEN = 256 };
enum eParams {
OVERLAY_DITHER,
OVERLAY_TRANSFORM,
OVERLAY_TRANSFORM_UI
};
struct Params{
Params(eParams p, int v) : param(p), value(v) {}
eParams param;
int value;
};
/** /**
* Rotator flags: not to be confused with orientation flags. * Rotator flags: not to be confused with orientation flags.
* Ususally, you want to open the rotator to make sure it is * Ususally, you want to open the rotator to make sure it is
@@ -267,19 +250,6 @@ enum eRotFlags {
ROT_FLAG_ENABLED = 1 // needed in rot ROT_FLAG_ENABLED = 1 // needed in rot
}; };
/* Used for rotator open.
* FIXME that is default, might be configs */
enum { ROT_NUM_BUFS = 2 };
/* Wait/No wait for waiting for vsync
* WAIT - wait for vsync, ignore fb (no need to compose w/ fb)
* NO_WAIT - do not wait for vsync and return immediatly since
* we need to run composition code */
enum eWait {
WAIT,
NO_WAIT
};
/* The values for is_fg flag for control alpha and transp /* The values for is_fg flag for control alpha and transp
* IS_FG_OFF means is_fg = 0 * IS_FG_OFF means is_fg = 0
* IS_FG_SET means is_fg = 1 * IS_FG_SET means is_fg = 1
@@ -298,15 +268,17 @@ enum eMdpFlags {
OV_MDP_FLAGS_NONE = 0, OV_MDP_FLAGS_NONE = 0,
OV_MDP_PIPE_SHARE = MDP_OV_PIPE_SHARE, OV_MDP_PIPE_SHARE = MDP_OV_PIPE_SHARE,
OV_MDP_DEINTERLACE = MDP_DEINTERLACE, OV_MDP_DEINTERLACE = MDP_DEINTERLACE,
OV_MDP_PLAY_NOWAIT = MDP_OV_PLAY_NOWAIT, OV_MDP_PLAY_NOWAIT = MDP_OV_PLAY_NOWAIT, //deprecated
OV_MDP_SECURE_OVERLAY_SESSION = MDP_SECURE_OVERLAY_SESSION OV_MDP_SECURE_OVERLAY_SESSION = MDP_SECURE_OVERLAY_SESSION,
OV_MDP_SOURCE_ROTATED_90 = MDP_SOURCE_ROTATED_90,
OV_MDP_MEMORY_ID_TYPE_FB = MDP_MEMORY_ID_TYPE_FB,
}; };
enum eOverlayPipeType { enum eOverlayPipeType {
OV_PIPE_TYPE_NULL, OV_PIPE_TYPE_NULL,
OV_PIPE_TYPE_BYPASS, OV_PIPE_TYPE_BYPASS,
OV_PIPE_TYPE_GENERIC, OV_PIPE_TYPE_GENERIC,
OV_PIPE_TYPE_HDMI, OV_PIPE_TYPE_VIDEO_EXT,
OV_PIPE_TYPE_M3D_EXTERNAL, OV_PIPE_TYPE_M3D_EXTERNAL,
OV_PIPE_TYPE_M3D_PRIMARY, OV_PIPE_TYPE_M3D_PRIMARY,
OV_PIPE_TYPE_RGB, OV_PIPE_TYPE_RGB,
@@ -327,24 +299,12 @@ enum eMdpPipeType {
OV_MDP_PIPE_VG OV_MDP_PIPE_VG
}; };
/* Corresponds to pipes in eDest */
enum eChannel {
CHANNEL_0,
CHANNEL_1,
CHANNEL_2
};
// Max pipes via overlay (VG0, VG1, RGB1) // Max pipes via overlay (VG0, VG1, RGB1)
enum { MAX_PIPES = 3 }; enum { MAX_PIPES = 3 };
/* Used to identify destination channels and /* Used to identify destination channels and
* also 3D channels e.g. when in 3D mode with 2 * also 3D channels e.g. when in 3D mode with 2
* pipes opened and it is used in get crop/pos 3D * pipes opened and it is used in get crop/pos 3D
*
* PLEASE NOTE : DO NOT USE eDest FOR ARRAYS
* i.e. args[OV_PIPE1] since it is a BIT MASK
* use CHANNELS enum instead. Each OV_PIPEX is
* not specific to a display (primary/external).
* */ * */
enum eDest { enum eDest {
OV_PIPE0 = 1 << 0, OV_PIPE0 = 1 << 0,
@@ -357,15 +317,21 @@ enum eDest {
enum eTransform { enum eTransform {
/* No rot */ /* No rot */
OVERLAY_TRANSFORM_0 = 0x0, OVERLAY_TRANSFORM_0 = 0x0,
/* flip source image horizontally */ /* flip source image horizontally 0x1 */
OVERLAY_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H, OVERLAY_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H,
/* flip source image vertically */ /* flip source image vertically 0x2 */
OVERLAY_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, OVERLAY_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
/* rotate source image 90 degrees */
OVERLAY_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
/* rotate source image 180 degrees /* rotate source image 180 degrees
* It is basically bit-or-ed H | V == 0x3 */ * It is basically bit-or-ed H | V == 0x3 */
OVERLAY_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, OVERLAY_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
/* rotate source image 90 degrees 0x4 */
OVERLAY_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
/* rotate source image 90 degrees and flip horizontally 0x5 */
OVERLAY_TRANSFORM_ROT_90_FLIP_H = HAL_TRANSFORM_ROT_90 |
HAL_TRANSFORM_FLIP_H,
/* rotate source image 90 degrees and flip vertically 0x6 */
OVERLAY_TRANSFORM_ROT_90_FLIP_V = HAL_TRANSFORM_ROT_90 |
HAL_TRANSFORM_FLIP_V,
/* rotate source image 270 degrees /* rotate source image 270 degrees
* Basically 180 | 90 == 0x7 */ * Basically 180 | 90 == 0x7 */
OVERLAY_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, OVERLAY_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
@@ -373,48 +339,28 @@ enum eTransform {
OVERLAY_TRANSFORM_INV = 0x80 OVERLAY_TRANSFORM_INV = 0x80
}; };
/* offset and fd are play info */
struct PlayInfo {
PlayInfo() : fd(-1), offset(0) {}
PlayInfo(int _fd, uint32_t _offset) :
fd(_fd), offset(_offset) {}
bool operator==(const PlayInfo& p) {
return (fd == p.fd && offset == p.offset);
}
int fd;
uint32_t offset;
};
// Used to consolidate pipe params // Used to consolidate pipe params
struct PipeArgs { struct PipeArgs {
PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE), PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE),
orientation(OVERLAY_TRANSFORM_0),
wait(NO_WAIT),
zorder(Z_SYSTEM_ALLOC), zorder(Z_SYSTEM_ALLOC),
isFg(IS_FG_OFF), isFg(IS_FG_OFF),
rotFlags(ROT_FLAG_DISABLED){ rotFlags(ROT_FLAG_DISABLED){
} }
PipeArgs(eMdpFlags f, eTransform o, PipeArgs(eMdpFlags f, Whf _whf,
Whf _whf, eWait w,
eZorder z, eIsFg fg, eRotFlags r) : eZorder z, eIsFg fg, eRotFlags r) :
mdpFlags(f), mdpFlags(f),
orientation(o),
whf(_whf), whf(_whf),
wait(w),
zorder(z), zorder(z),
isFg(fg), isFg(fg),
rotFlags(r) { rotFlags(r) {
} }
eMdpFlags mdpFlags; // for mdp_overlay flags PIPE_SHARE, NO_WAIT, etc eMdpFlags mdpFlags; // for mdp_overlay flags
eTransform orientation; // FIXME docs
Whf whf; Whf whf;
eWait wait; // flags WAIT/NO_WAIT
eZorder zorder; // stage number eZorder zorder; // stage number
eIsFg isFg; // control alpha & transp eIsFg isFg; // control alpha & transp
eRotFlags rotFlags; eRotFlags rotFlags;
PlayInfo play;
}; };
enum eOverlayState{ enum eOverlayState{
@@ -464,21 +410,13 @@ enum {
WFD = 2 WFD = 2
}; };
//TODO Make this a part of some appropriate class
static int sExtType = HDMI; //HDMI or WFD static int sExtType = HDMI; //HDMI or WFD
//Set by client as HDMI/WFD //Set by client as HDMI/WFD
static inline void setExtType(const int& type) { void setExtType(const int& type);
if(type != HDMI || type != WFD) {
ALOGE("%s: Unrecognized type %d", __func__, type);
return;
}
sExtType = type;
}
//Return External panel type set by client. //Return External panel type set by client.
static inline int getExtType() { int getExtType();
return sExtType;
}
//Gets the FB number for the external type. //Gets the FB number for the external type.
//As of now, HDMI always has fb1, WFD could use fb1 or fb2 //As of now, HDMI always has fb1, WFD could use fb1 or fb2
@@ -503,6 +441,7 @@ static int getFBForPanel(int panel) { // PRIMARY OR EXTERNAL
} }
// number of rgb pipes bufs (max) // number of rgb pipes bufs (max)
// 2 for rgb0/1 double bufs // 2 for rgb0/1 double bufs
enum { RGB_PIPE_NUM_BUFS = 2 }; enum { RGB_PIPE_NUM_BUFS = 2 };
@@ -524,52 +463,17 @@ int getRotOutFmt(uint32_t format);
* rotation is 90, 180 etc * rotation is 90, 180 etc
* It returns MDP related enum/define that match rot+flip*/ * It returns MDP related enum/define that match rot+flip*/
int getMdpOrient(eTransform rotation); int getMdpOrient(eTransform rotation);
uint32_t getSize(const Whf& whf);
uint32_t getSizeByMdp(const Whf& whf);
const char* getFormatString(uint32_t format); const char* getFormatString(uint32_t format);
const char* getStateString(eOverlayState state); const char* getStateString(eOverlayState state);
inline int setWait(eWait wait, int flags) {
return (wait == WAIT) ?
flags &= ~MDP_OV_PLAY_NOWAIT :
flags |= MDP_OV_PLAY_NOWAIT;
}
/* possible overlay formats libhardware/include/hardware/hardware.h */
enum eFormat {
OVERLAY_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888,
OVERLAY_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565,
OVERLAY_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888,
OVERLAY_FORMAT_YCbYCr_422_I = 0x14,
OVERLAY_FORMAT_CbYCrY_422_I = 0x16,
OVERLAY_FORMAT_DEFAULT = 99 // The actual color format is
// determined by the overlay
};
// Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time // Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
// of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define // of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define
enum { HW_OV_MAGNIFICATION_LIMIT = 20, enum { HW_OV_MAGNIFICATION_LIMIT = 20,
HW_OV_MINIFICATION_LIMIT = 8 HW_OV_MINIFICATION_LIMIT = 8
}; };
inline bool rotated(int orie) {
return (orie == OVERLAY_TRANSFORM_ROT_90 ||
orie == OVERLAY_TRANSFORM_ROT_270);
}
/* used by crop funcs in order to
* normalizes the crop values to be all even */
void normalizeCrop(uint32_t& xy, uint32_t& wh);
template <class T> template <class T>
inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); } inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); }
template <class ROT, class MDP>
inline void swapOVRotWidthHeight(ROT& rot, MDP& mdp)
{
mdp.swapSrcWH();
mdp.swapSrcRectWH();
rot.swapDstWH();
}
template <class T> inline void swap ( T& a, T& b ) template <class T> inline void swap ( T& a, T& b )
{ {
@@ -587,35 +491,6 @@ inline int align(int value, int a) {
return a ? ((value + (a-1)) & ~(a-1)) : value; return a ? ((value + (a-1)) & ~(a-1)) : value;
} }
template <class MDP>
inline utils::Dim getSrcRectDim(const MDP& ov) {
return utils::Dim(ov.src_rect.x,
ov.src_rect.y,
ov.src_rect.w,
ov.src_rect.h);
}
template <class MDP>
inline utils::Whf getSrcWhf(const MDP& ov) {
return utils::Whf(ov.src.width,
ov.src.height,
ov.src.format);
}
template <class MDP>
inline void setSrcRectDim(MDP& ov, const utils::Dim& d) {
ov.src_rect.x = d.x;
ov.src_rect.y = d.y;
ov.src_rect.w = d.w;
ov.src_rect.h = d.h;
}
template <class MDP>
inline void setSrcWhf(MDP& ov, const utils::Whf& whf) {
ov.src.width = whf.w;
ov.src.height = whf.h;
ov.src.format = whf.format;
}
enum eRotOutFmt { enum eRotOutFmt {
ROT_OUT_FMT_DEFAULT, ROT_OUT_FMT_DEFAULT,
ROT_OUT_FMT_Y_CRCB_H2V2 ROT_OUT_FMT_Y_CRCB_H2V2
@@ -691,21 +566,30 @@ inline const char* getFormatString(uint32_t format){
"MDP_RGB_565", "MDP_RGB_565",
"MDP_XRGB_8888", "MDP_XRGB_8888",
"MDP_Y_CBCR_H2V2", "MDP_Y_CBCR_H2V2",
"MDP_Y_CBCR_H2V2_ADRENO",
"MDP_ARGB_8888", "MDP_ARGB_8888",
"MDP_RGB_888", "MDP_RGB_888",
"MDP_Y_CRCB_H2V2", "MDP_Y_CRCB_H2V2",
"MDP_YCRYCB_H2V1", "MDP_YCRYCB_H2V1",
"MDP_Y_CRCB_H2V1", "MDP_Y_CRCB_H2V1",
"MDP_Y_CBCR_H2V1", "MDP_Y_CBCR_H2V1",
"MDP_Y_CRCB_H1V2",
"MDP_Y_CBCR_H1V2",
"MDP_RGBA_8888", "MDP_RGBA_8888",
"MDP_BGRA_8888", "MDP_BGRA_8888",
"MDP_RGBX_8888", "MDP_RGBX_8888",
"MDP_Y_CRCB_H2V2_TILE", "MDP_Y_CRCB_H2V2_TILE",
"MDP_Y_CBCR_H2V2_TILE", "MDP_Y_CBCR_H2V2_TILE",
"MDP_Y_CR_CB_H2V2", "MDP_Y_CR_CB_H2V2",
"MDP_Y_CR_CB_GH2V2",
"MDP_Y_CB_CR_H2V2", "MDP_Y_CB_CR_H2V2",
"MDP_IMGTYPE_LIMIT", "MDP_Y_CRCB_H1V1",
"MDP_Y_CBCR_H1V1",
"MDP_YCRCB_H1V1",
"MDP_YCBCR_H1V1",
"MDP_BGR_565", "MDP_BGR_565",
"MDP_IMGTYPE_LIMIT",
"MDP_RGB_BORDERFILL",
"MDP_FB_FORMAT", "MDP_FB_FORMAT",
"MDP_IMGTYPE_LIMIT2" "MDP_IMGTYPE_LIMIT2"
}; };
@@ -746,15 +630,6 @@ inline const char* getStateString(eOverlayState state){
return "BAD_STATE"; return "BAD_STATE";
} }
inline uint32_t getSizeByMdp(const Whf& whf) {
Whf _whf(whf);
int fmt = getMdpFormat(whf.format);
OVASSERT(-1 != fmt, "getSizeByMdp error in format %d",
whf.format);
_whf.format = fmt;
return getSize(_whf);
}
inline void Whf::dump() const { inline void Whf::dump() const {
ALOGE("== Dump WHF w=%d h=%d f=%d s=%d start/end ==", ALOGE("== Dump WHF w=%d h=%d f=%d s=%d start/end ==",
w, h, format, size); w, h, format, size);
@@ -766,18 +641,18 @@ inline void Dim::dump() const {
inline int getMdpOrient(eTransform rotation) { inline int getMdpOrient(eTransform rotation) {
ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, rotation); ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, rotation);
switch(int(rotation)) switch(rotation)
{ {
case OVERLAY_TRANSFORM_0 : return 0; case OVERLAY_TRANSFORM_0 : return 0;
case HAL_TRANSFORM_FLIP_V: return MDP_FLIP_UD; case OVERLAY_TRANSFORM_FLIP_V: return MDP_FLIP_UD;
case HAL_TRANSFORM_FLIP_H: return MDP_FLIP_LR; case OVERLAY_TRANSFORM_FLIP_H: return MDP_FLIP_LR;
case HAL_TRANSFORM_ROT_90: return MDP_ROT_90; case OVERLAY_TRANSFORM_ROT_90: return MDP_ROT_90;
case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V: case OVERLAY_TRANSFORM_ROT_90_FLIP_V:
return MDP_ROT_90|MDP_FLIP_LR; return MDP_ROT_90 | MDP_FLIP_UD;
case HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H: case OVERLAY_TRANSFORM_ROT_90_FLIP_H:
return MDP_ROT_90|MDP_FLIP_UD; return MDP_ROT_90 | MDP_FLIP_LR;
case HAL_TRANSFORM_ROT_180: return MDP_ROT_180; case OVERLAY_TRANSFORM_ROT_180: return MDP_ROT_180;
case HAL_TRANSFORM_ROT_270: return MDP_ROT_270; case OVERLAY_TRANSFORM_ROT_270: return MDP_ROT_270;
default: default:
ALOGE("%s: invalid rotation value (value = 0x%x", ALOGE("%s: invalid rotation value (value = 0x%x",
__FUNCTION__, rotation); __FUNCTION__, rotation);
@@ -801,28 +676,11 @@ inline int getRotOutFmt(uint32_t format) {
return -1; return -1;
} }
template<>
struct RotOutFmt<ROT_OUT_FMT_DEFAULT>
{
static inline int fmt(uint32_t format) {
return getRotOutFmt(format);
}
};
template<>
struct RotOutFmt<ROT_OUT_FMT_Y_CRCB_H2V2>
{
static inline int fmt(uint32_t) {
return MDP_Y_CRCB_H2V2;
}
};
inline uint32_t getColorFormat(uint32_t format) inline uint32_t getColorFormat(uint32_t format)
{ {
//XXX: Earlier this used to mask the format return (format == HAL_PIXEL_FORMAT_YV12) ?
//to check for interlaced or 3D. Just return format : colorFormat(format);
//the format now
return format;
} }
// FB0 // FB0
@@ -937,43 +795,6 @@ inline void ScreenInfo::dump(const char* const s) const {
s, mFBWidth, mFBHeight, mFBbpp, mFBystride); s, mFBWidth, mFBHeight, mFBbpp, mFBystride);
} }
inline void setSrcRectDim(const overlay::utils::Dim d,
mdp_overlay& ov) {
ov.src_rect.x = d.x;
ov.src_rect.y = d.y;
ov.src_rect.w = d.w;
ov.src_rect.h = d.h;
}
inline void setDstRectDim(const overlay::utils::Dim d,
mdp_overlay& ov) {
ov.dst_rect.x = d.x;
ov.dst_rect.y = d.y;
ov.dst_rect.w = d.w;
ov.dst_rect.h = d.h;
}
inline overlay::utils::Whf getSrcWhf(const mdp_overlay& ov) {
return overlay::utils::Whf(ov.src.width,
ov.src.height,
ov.src.format);
}
inline overlay::utils::Dim getSrcRectDim(const mdp_overlay& ov) {
return overlay::utils::Dim(ov.src_rect.x,
ov.src_rect.y,
ov.src_rect.w,
ov.src_rect.h);
}
inline overlay::utils::Dim getDstRectDim(const mdp_overlay& ov) {
return overlay::utils::Dim(ov.dst_rect.x,
ov.dst_rect.y,
ov.dst_rect.w,
ov.dst_rect.h);
}
} // namespace utils ends } // namespace utils ends
//--------------------Class Res stuff (namespace overlay only) ----------- //--------------------Class Res stuff (namespace overlay only) -----------
@@ -981,7 +802,7 @@ inline overlay::utils::Dim getDstRectDim(const mdp_overlay& ov) {
class Res { class Res {
public: public:
// /dev/graphics/fb%u // /dev/graphics/fb%u
static const char* const devTemplate; static const char* const fbPath;
// /dev/msm_rotator // /dev/msm_rotator
static const char* const rotPath; static const char* const rotPath;
// /sys/class/graphics/fb1/format_3d // /sys/class/graphics/fb1/format_3d
@@ -1060,7 +881,9 @@ inline OvFD::OvFD() : mFD (INVAL) {
mPath[0] = 0; mPath[0] = 0;
} }
inline OvFD::~OvFD() { /* no op in the meantime */ } inline OvFD::~OvFD() {
//no op since copy() can be used to share fd, in 3d cases.
}
inline bool OvFD::open(const char* const dev, int flags) inline bool OvFD::open(const char* const dev, int flags)
{ {

View File

@@ -50,20 +50,15 @@ public:
/* Please look at overlayGenPipe.h for info */ /* Please look at overlayGenPipe.h for info */
explicit M3DExtPipe(); explicit M3DExtPipe();
~M3DExtPipe(); ~M3DExtPipe();
bool open(RotatorBase* rot); bool init(RotatorBase* rot);
bool close(); bool close();
bool commit(); bool commit();
void setId(int id); bool queueBuffer(int fd, uint32_t offset);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync(); bool waitForVsync();
bool setCrop(const utils::Dim& d); bool setCrop(const utils::Dim& d);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim); bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param); bool setTransform(const utils::eTransform& param);
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const; utils::eOverlayPipeType getOvPipeType() const;
void dump() const; void dump() const;
private: private:
@@ -87,20 +82,15 @@ public:
/* Please look at overlayGenPipe.h for info */ /* Please look at overlayGenPipe.h for info */
explicit M3DPrimaryPipe(); explicit M3DPrimaryPipe();
~M3DPrimaryPipe(); ~M3DPrimaryPipe();
bool open(RotatorBase* rot); bool init(RotatorBase* rot);
bool close(); bool close();
bool commit(); bool commit();
void setId(int id); bool queueBuffer(int fd, uint32_t offset);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync(); bool waitForVsync();
bool setCrop(const utils::Dim& d); bool setCrop(const utils::Dim& d);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim); bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param); bool setTransform(const utils::eTransform& param);
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const; utils::eOverlayPipeType getOvPipeType() const;
void dump() const; void dump() const;
private: private:
@@ -124,20 +114,15 @@ public:
/* Please look at overlayGenPipe.h for info */ /* Please look at overlayGenPipe.h for info */
explicit S3DExtPipe(); explicit S3DExtPipe();
~S3DExtPipe(); ~S3DExtPipe();
bool open(RotatorBase* rot); bool init(RotatorBase* rot);
bool close(); bool close();
bool commit(); bool commit();
void setId(int id); bool queueBuffer(int fd, uint32_t offset);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync(); bool waitForVsync();
bool setCrop(const utils::Dim& d); bool setCrop(const utils::Dim& d);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim); bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param); bool setTransform(const utils::eTransform& param);
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const; utils::eOverlayPipeType getOvPipeType() const;
void dump() const; void dump() const;
private: private:
@@ -161,20 +146,15 @@ public:
/* Please look at overlayGenPipe.h for info */ /* Please look at overlayGenPipe.h for info */
explicit S3DPrimaryPipe(); explicit S3DPrimaryPipe();
~S3DPrimaryPipe(); ~S3DPrimaryPipe();
bool open(RotatorBase* rot); bool init(RotatorBase* rot);
bool close(); bool close();
bool commit(); bool commit();
void setId(int id); bool queueBuffer(int fd, uint32_t offset);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync(); bool waitForVsync();
bool setCrop(const utils::Dim& d); bool setCrop(const utils::Dim& d);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim); bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param); bool setTransform(const utils::eTransform& param);
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const; utils::eOverlayPipeType getOvPipeType() const;
void dump() const; void dump() const;
private: private:
@@ -197,10 +177,10 @@ inline M3DExtPipe<CHAN>::M3DExtPipe() : mM3Dfmt(0) {}
template <int CHAN> template <int CHAN>
inline M3DExtPipe<CHAN>::~M3DExtPipe() { close(); } inline M3DExtPipe<CHAN>::~M3DExtPipe() { close(); }
template <int CHAN> template <int CHAN>
inline bool M3DExtPipe<CHAN>::open(RotatorBase* rot) { inline bool M3DExtPipe<CHAN>::init(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "M3DExtPipe open"); ALOGE_IF(DEBUG_OVERLAY, "M3DExtPipe init");
if(!mM3d.open(rot)) { if(!mM3d.init(rot)) {
ALOGE("3Dpipe failed to open"); ALOGE("3Dpipe failed to init");
return false; return false;
} }
return true; return true;
@@ -212,15 +192,9 @@ inline bool M3DExtPipe<CHAN>::close() {
template <int CHAN> template <int CHAN>
inline bool M3DExtPipe<CHAN>::commit() { return mM3d.commit(); } inline bool M3DExtPipe<CHAN>::commit() { return mM3d.commit(); }
template <int CHAN> template <int CHAN>
inline void M3DExtPipe<CHAN>::setId(int id) { mM3d.setId(id); } inline bool M3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
template <int CHAN> return mM3d.queueBuffer(fd, offset);
inline void M3DExtPipe<CHAN>::setMemoryId(int id) { mM3d.setMemoryId(id); } }
template <int CHAN>
inline bool M3DExtPipe<CHAN>::queueBuffer(uint32_t offset) {
return mM3d.queueBuffer(offset); }
template <int CHAN>
inline bool M3DExtPipe<CHAN>::dequeueBuffer(void*& buf) {
return mM3d.dequeueBuffer(buf); }
template <int CHAN> template <int CHAN>
inline bool M3DExtPipe<CHAN>::waitForVsync() { inline bool M3DExtPipe<CHAN>::waitForVsync() {
return mM3d.waitForVsync(); } return mM3d.waitForVsync(); }
@@ -233,14 +207,7 @@ inline bool M3DExtPipe<CHAN>::setCrop(const utils::Dim& d) {
} }
return mM3d.setCrop(_dim); return mM3d.setCrop(_dim);
} }
template <int CHAN>
inline bool M3DExtPipe<CHAN>::start(const utils::PipeArgs& args) {
if(!mM3d.start(args)) {
ALOGE("M3DExtPipe start failed");
return false;
}
return true;
}
template <int CHAN> template <int CHAN>
inline bool M3DExtPipe<CHAN>::setPosition(const utils::Dim& d) { inline bool M3DExtPipe<CHAN>::setPosition(const utils::Dim& d) {
utils::Dim _dim; utils::Dim _dim;
@@ -258,8 +225,8 @@ inline bool M3DExtPipe<CHAN>::setPosition(const utils::Dim& d) {
return mM3d.setPosition(_dim); return mM3d.setPosition(_dim);
} }
template <int CHAN> template <int CHAN>
inline bool M3DExtPipe<CHAN>::setParameter(const utils::Params& param) { inline bool M3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) {
return mM3d.setParameter(param); return mM3d.setTransform(param);
} }
template <int CHAN> template <int CHAN>
inline bool M3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) inline bool M3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args)
@@ -267,19 +234,9 @@ inline bool M3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args)
// extract 3D fmt // extract 3D fmt
mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) | mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) |
utils::HAL_3D_OUT_MONOS_MASK; utils::HAL_3D_OUT_MONOS_MASK;
if(mM3d.isClosed()){
if(!this->start(args)) {
ALOGE("M3DExtPipe setSource failed to start");
return false;
}
}
return mM3d.setSource(args); return mM3d.setSource(args);
} }
template <int CHAN> template <int CHAN>
inline const utils::PipeArgs& M3DExtPipe<CHAN>::getArgs() const {
return mM3d.getArgs();
}
template <int CHAN>
inline utils::eOverlayPipeType M3DExtPipe<CHAN>::getOvPipeType() const { inline utils::eOverlayPipeType M3DExtPipe<CHAN>::getOvPipeType() const {
return utils::OV_PIPE_TYPE_M3D_EXTERNAL; return utils::OV_PIPE_TYPE_M3D_EXTERNAL;
} }
@@ -296,10 +253,10 @@ inline M3DPrimaryPipe<CHAN>::M3DPrimaryPipe() : mM3Dfmt(0) {}
template <int CHAN> template <int CHAN>
inline M3DPrimaryPipe<CHAN>::~M3DPrimaryPipe() { close(); } inline M3DPrimaryPipe<CHAN>::~M3DPrimaryPipe() { close(); }
template <int CHAN> template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::open(RotatorBase* rot) { inline bool M3DPrimaryPipe<CHAN>::init(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "M3DPrimaryPipe open"); ALOGE_IF(DEBUG_OVERLAY, "M3DPrimaryPipe init");
if(!mM3d.open(rot)) { if(!mM3d.init(rot)) {
ALOGE("3Dpipe failed to open"); ALOGE("3Dpipe failed to init");
return false; return false;
} }
return true; return true;
@@ -311,15 +268,9 @@ inline bool M3DPrimaryPipe<CHAN>::close() {
template <int CHAN> template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::commit() { return mM3d.commit(); } inline bool M3DPrimaryPipe<CHAN>::commit() { return mM3d.commit(); }
template <int CHAN> template <int CHAN>
inline void M3DPrimaryPipe<CHAN>::setId(int id) { mM3d.setId(id); } inline bool M3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
template <int CHAN> return mM3d.queueBuffer(fd, offset);
inline void M3DPrimaryPipe<CHAN>::setMemoryId(int id) { mM3d.setMemoryId(id); } }
template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::queueBuffer(uint32_t offset) {
return mM3d.queueBuffer(offset); }
template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::dequeueBuffer(void*& buf) {
return mM3d.dequeueBuffer(buf); }
template <int CHAN> template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::waitForVsync() { inline bool M3DPrimaryPipe<CHAN>::waitForVsync() {
return mM3d.waitForVsync(); } return mM3d.waitForVsync(); }
@@ -333,20 +284,12 @@ inline bool M3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) {
return mM3d.setCrop(_dim); return mM3d.setCrop(_dim);
} }
template <int CHAN> template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::start(const utils::PipeArgs& args) {
if(!mM3d.start(args)) {
ALOGE("M3DPrimaryPipe start failed");
return false;
}
return true;
}
template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) { inline bool M3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) {
return mM3d.setPosition(d); return mM3d.setPosition(d);
} }
template <int CHAN> template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::setParameter(const utils::Params& param) { inline bool M3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) {
return mM3d.setParameter(param); return mM3d.setTransform(param);
} }
template <int CHAN> template <int CHAN>
inline bool M3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args) inline bool M3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
@@ -354,19 +297,9 @@ inline bool M3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
// extract 3D fmt // extract 3D fmt
mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) | mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) |
utils::HAL_3D_OUT_MONOS_MASK; utils::HAL_3D_OUT_MONOS_MASK;
if (mM3d.isClosed()) {
if (!this->start(args)) {
ALOGE("M3DPrimaryPipe setSource failed to start");
return false;
}
}
return mM3d.setSource(args); return mM3d.setSource(args);
} }
template <int CHAN> template <int CHAN>
inline const utils::PipeArgs& M3DPrimaryPipe<CHAN>::getArgs() const {
return mM3d.getArgs();
}
template <int CHAN>
inline utils::eOverlayPipeType M3DPrimaryPipe<CHAN>::getOvPipeType() const { inline utils::eOverlayPipeType M3DPrimaryPipe<CHAN>::getOvPipeType() const {
return utils::OV_PIPE_TYPE_M3D_PRIMARY; return utils::OV_PIPE_TYPE_M3D_PRIMARY;
} }
@@ -382,10 +315,10 @@ inline S3DExtPipe<CHAN>::S3DExtPipe() : mS3Dfmt(0) {}
template <int CHAN> template <int CHAN>
inline S3DExtPipe<CHAN>::~S3DExtPipe() { close(); } inline S3DExtPipe<CHAN>::~S3DExtPipe() { close(); }
template <int CHAN> template <int CHAN>
inline bool S3DExtPipe<CHAN>::open(RotatorBase* rot) { inline bool S3DExtPipe<CHAN>::init(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "S3DExtPipe open"); ALOGE_IF(DEBUG_OVERLAY, "S3DExtPipe init");
if(!mS3d.open(rot)) { if(!mS3d.init(rot)) {
ALOGE("3Dpipe failed to open"); ALOGE("3Dpipe failed to init");
return false; return false;
} }
return true; return true;
@@ -400,16 +333,9 @@ inline bool S3DExtPipe<CHAN>::close() {
template <int CHAN> template <int CHAN>
inline bool S3DExtPipe<CHAN>::commit() { return mS3d.commit(); } inline bool S3DExtPipe<CHAN>::commit() { return mS3d.commit(); }
template <int CHAN> template <int CHAN>
inline void S3DExtPipe<CHAN>::setId(int id) { mS3d.setId(id); } inline bool S3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
template <int CHAN> return mS3d.queueBuffer(fd, offset);
inline void S3DExtPipe<CHAN>::setMemoryId(int id) { mS3d.setMemoryId(id); } }
template <int CHAN>
inline bool S3DExtPipe<CHAN>::queueBuffer(uint32_t offset) {
//this->dump();
return mS3d.queueBuffer(offset); }
template <int CHAN>
inline bool S3DExtPipe<CHAN>::dequeueBuffer(void*& buf) {
return mS3d.dequeueBuffer(buf); }
template <int CHAN> template <int CHAN>
inline bool S3DExtPipe<CHAN>::waitForVsync() { inline bool S3DExtPipe<CHAN>::waitForVsync() {
return mS3d.waitForVsync(); } return mS3d.waitForVsync(); }
@@ -423,20 +349,6 @@ inline bool S3DExtPipe<CHAN>::setCrop(const utils::Dim& d) {
return mS3d.setCrop(_dim); return mS3d.setCrop(_dim);
} }
template <int CHAN> template <int CHAN>
inline bool S3DExtPipe<CHAN>::start(const utils::PipeArgs& args) {
OVASSERT(mS3Dfmt, "S3DExtPipe mS3Dfmt should not be 0 here");
if(!mS3d.start(args)) {
ALOGE("S3DExtPipe start failed");
return false;
}
uint32_t fmt = mS3Dfmt & utils::OUTPUT_3D_MASK;
if(!utils::send3DInfoPacket(fmt)){
ALOGE("Error S3DExtPipe start error send3DInfoPacket %d", fmt);
return false;
}
return true;
}
template <int CHAN>
inline bool S3DExtPipe<CHAN>::setPosition(const utils::Dim& d) inline bool S3DExtPipe<CHAN>::setPosition(const utils::Dim& d)
{ {
utils::Dim _dim; utils::Dim _dim;
@@ -450,25 +362,15 @@ inline bool S3DExtPipe<CHAN>::setPosition(const utils::Dim& d)
return mS3d.setPosition(_dim); return mS3d.setPosition(_dim);
} }
template <int CHAN> template <int CHAN>
inline bool S3DExtPipe<CHAN>::setParameter(const utils::Params& param) { inline bool S3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) {
return mS3d.setParameter(param); return mS3d.setTransform(param);
} }
template <int CHAN> template <int CHAN>
inline bool S3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) { inline bool S3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) {
mS3Dfmt = utils::getS3DFormat(args.whf.format); mS3Dfmt = utils::getS3DFormat(args.whf.format);
if(mS3d.isClosed()){
if(!this->start(args)) {
ALOGE("S3DExtPipe setSource failed to start");
return false;
}
}
return mS3d.setSource(args); return mS3d.setSource(args);
} }
template <int CHAN> template <int CHAN>
inline const utils::PipeArgs& S3DExtPipe<CHAN>::getArgs() const {
return mS3d.getArgs();
}
template <int CHAN>
inline utils::eOverlayPipeType S3DExtPipe<CHAN>::getOvPipeType() const { inline utils::eOverlayPipeType S3DExtPipe<CHAN>::getOvPipeType() const {
return utils::OV_PIPE_TYPE_S3D_EXTERNAL; return utils::OV_PIPE_TYPE_S3D_EXTERNAL;
} }
@@ -484,10 +386,10 @@ inline S3DPrimaryPipe<CHAN>::S3DPrimaryPipe() : mS3Dfmt(0) {}
template <int CHAN> template <int CHAN>
inline S3DPrimaryPipe<CHAN>::~S3DPrimaryPipe() { close(); } inline S3DPrimaryPipe<CHAN>::~S3DPrimaryPipe() { close(); }
template <int CHAN> template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::open(RotatorBase* rot) { inline bool S3DPrimaryPipe<CHAN>::init(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "S3DPrimaryPipe open"); ALOGE_IF(DEBUG_OVERLAY, "S3DPrimaryPipe init");
if(!mS3d.open(rot)) { if(!mS3d.init(rot)) {
ALOGE("3Dpipe failed to open"); ALOGE("3Dpipe failed to init");
return false; return false;
} }
// set the ctrl fd // set the ctrl fd
@@ -502,18 +404,20 @@ inline bool S3DPrimaryPipe<CHAN>::close() {
mCtrl3D.close(); mCtrl3D.close();
return mS3d.close(); return mS3d.close();
} }
template <int CHAN> template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::commit() { return mS3d.commit(); } inline bool S3DPrimaryPipe<CHAN>::commit() {
uint32_t fmt = mS3Dfmt & utils::OUTPUT_3D_MASK;
if(!utils::send3DInfoPacket(fmt)){
ALOGE("Error S3DExtPipe start error send3DInfoPacket %d", fmt);
return false;
}
return mS3d.commit();
}
template <int CHAN> template <int CHAN>
inline void S3DPrimaryPipe<CHAN>::setId(int id) { mS3d.setId(id); } inline bool S3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) {
template <int CHAN> return mS3d.queueBuffer(fd, offset);
inline void S3DPrimaryPipe<CHAN>::setMemoryId(int id) { mS3d.setMemoryId(id); } }
template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::queueBuffer(uint32_t offset) {
return mS3d.queueBuffer(offset); }
template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::dequeueBuffer(void*& buf) {
return mS3d.dequeueBuffer(buf); }
template <int CHAN> template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::waitForVsync() { inline bool S3DPrimaryPipe<CHAN>::waitForVsync() {
return mS3d.waitForVsync(); } return mS3d.waitForVsync(); }
@@ -527,14 +431,6 @@ inline bool S3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) {
return mS3d.setCrop(_dim); return mS3d.setCrop(_dim);
} }
template <int CHAN> template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::start(const utils::PipeArgs& args) {
if(!mS3d.start(args)) {
ALOGE("S3DPrimaryPipe start failed");
return false;
}
return true;
}
template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) inline bool S3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d)
{ {
utils::Whf fbwhf(mS3d.getScreenInfo().mFBWidth, utils::Whf fbwhf(mS3d.getScreenInfo().mFBWidth,
@@ -562,13 +458,12 @@ inline bool S3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d)
* So the easiest way to achieve it, is to make sure FB0 is having it before * So the easiest way to achieve it, is to make sure FB0 is having it before
* setParam is running */ * setParam is running */
template <> template <>
inline bool S3DPrimaryPipe<utils::OV_PIPE0>::setParameter( inline bool S3DPrimaryPipe<utils::OV_PIPE0>::setTransform(
const utils::Params& param) { const utils::eTransform& param) {
if(utils::OVERLAY_TRANSFORM == param.param){
uint32_t barrier=0; uint32_t barrier=0;
switch(param.value) { switch(param) {
case HAL_TRANSFORM_ROT_90: case utils::OVERLAY_TRANSFORM_ROT_90:
case HAL_TRANSFORM_ROT_270: case utils::OVERLAY_TRANSFORM_ROT_270:
barrier = utils::BARRIER_LAND; barrier = utils::BARRIER_LAND;
break; break;
default: default:
@@ -576,33 +471,22 @@ inline bool S3DPrimaryPipe<utils::OV_PIPE0>::setParameter(
break; break;
} }
if(!utils::enableBarrier(barrier)) { if(!utils::enableBarrier(barrier)) {
ALOGE("S3DPrimaryPipe setParameter failed to enable barrier"); ALOGE("S3DPrimaryPipe setTransform failed to enable barrier");
} }
} return mS3d.setTransform(param);
return mS3d.setParameter(param);
} }
template <int CHAN> template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::setParameter(const utils::Params& param) { inline bool S3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) {
return mS3d.setParameter(param); return mS3d.setTransform(param);
} }
template <int CHAN> template <int CHAN>
inline bool S3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args) inline bool S3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args)
{ {
mS3Dfmt = utils::getS3DFormat(args.whf.format); mS3Dfmt = utils::getS3DFormat(args.whf.format);
if(mS3d.isClosed()){
if(!this->start(args)) {
ALOGE("S3DPrimaryPipe setSource failed to start");
return false;
}
}
return mS3d.setSource(args); return mS3d.setSource(args);
} }
template <int CHAN> template <int CHAN>
inline const utils::PipeArgs& S3DPrimaryPipe<CHAN>::getArgs() const {
return mS3d.getArgs();
}
template <int CHAN>
inline utils::eOverlayPipeType S3DPrimaryPipe<CHAN>::getOvPipeType() const { inline utils::eOverlayPipeType S3DPrimaryPipe<CHAN>::getOvPipeType() const {
return utils::OV_PIPE_TYPE_S3D_PRIMARY; return utils::OV_PIPE_TYPE_S3D_PRIMARY;
} }

View File

@@ -1,213 +0,0 @@
/*
* Copyright (c) 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.
*/
#ifndef OVERLAY_BYPASS_PIPE_H
#define OVERLAY_BYPASS_PIPE_H
#include "overlayGenPipe.h"
#include "overlayUtils.h"
#include "overlayCtrlData.h"
#include "overlayMdp.h"
#include "overlayRotator.h"
namespace overlay {
/* A specific impl of GenericPipe
* Whenever needed to have a pass through - we do it.
* If there is a special need for a different behavior - do it here
* PipeType = 0 (RGB), 1 (VG) */
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
class BypassPipe : utils::NoCopy {
public:
/* Please look at overlayGenPipe.h for info */
explicit BypassPipe();
~BypassPipe();
bool open(RotatorBase* rot);
bool close();
bool commit();
void setId(int id);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync();
bool setCrop(const utils::Dim& dim);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param);
bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const;
void dump() const;
private:
overlay::GenericPipe<ovutils::PRIMARY> mBypass;
};
//------------------Inlines and Templates---------------------
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline BypassPipe<PipeType, IsFg, Wait, Zorder>::BypassPipe() {}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline BypassPipe<PipeType, IsFg, Wait, Zorder>::~BypassPipe() {
close();
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::open(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "BypassPipe open");
return mBypass.open(rot);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::close() {
return mBypass.close();
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::commit() {
return mBypass.commit();
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline void BypassPipe<PipeType, IsFg, Wait, Zorder>::setId(int id) {
mBypass.setId(id);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline void BypassPipe<PipeType, IsFg, Wait, Zorder>::setMemoryId(int id) {
mBypass.setMemoryId(id);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::queueBuffer(
uint32_t offset) {
return mBypass.queueBuffer(offset);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::dequeueBuffer(
void*& buf) {
return mBypass.dequeueBuffer(buf);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::waitForVsync() {
return mBypass.waitForVsync();
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setCrop(
const utils::Dim& dim) {
return mBypass.setCrop(dim);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::start(
const utils::PipeArgs& args) {
return mBypass.start(args);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setPosition(
const utils::Dim& dim) {
return mBypass.setPosition(dim);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setParameter(
const utils::Params& param) {
return mBypass.setParameter(param);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline bool BypassPipe<PipeType, IsFg, Wait, Zorder>::setSource(
const utils::PipeArgs& args) {
utils::PipeArgs arg(args);
// Stride aligned to 32
arg.whf.w = utils::align(arg.whf.w, 32);
arg.whf.h = utils::align(arg.whf.h, 32);
// VG or RG pipe
if (PipeType == utils::OV_MDP_PIPE_VG) {
setMdpFlags(arg.mdpFlags, utils::OV_MDP_PIPE_SHARE);
}
// Set is_fg flag
arg.isFg = IsFg;
// Wait or no wait
arg.wait = Wait;
// Z-order
arg.zorder = Zorder;
return mBypass.setSource(arg);
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline const utils::PipeArgs& BypassPipe<PipeType, IsFg, Wait,
Zorder>::getArgs() const {
return mBypass.getArgs();
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline utils::eOverlayPipeType BypassPipe<PipeType, IsFg, Wait,
Zorder>::getOvPipeType() const {
return utils::OV_PIPE_TYPE_BYPASS;
}
template <utils::eMdpPipeType PipeType, utils::eIsFg IsFg, utils::eWait Wait,
utils::eZorder Zorder>
inline void BypassPipe<PipeType, IsFg, Wait, Zorder>::dump() const {
ALOGE("Bypass VG Pipe");
mBypass.dump();
}
} // overlay
#endif // OVERLAY_BYPASS_PIPE_H

View File

@@ -34,65 +34,38 @@
#include "overlayRotator.h" #include "overlayRotator.h"
#include "overlayCtrlData.h" #include "overlayCtrlData.h"
// FIXME make int to be uint32 whenever possible
namespace overlay { namespace overlay {
template <int PANEL> template <int PANEL>
class GenericPipe : utils::NoCopy { class GenericPipe : utils::NoCopy {
public: public:
/* ctor init */ /* ctor */
explicit GenericPipe(); explicit GenericPipe();
/* dtor */
/* dtor close */
~GenericPipe(); ~GenericPipe();
/* CTRL/DATA init. Not owning rotator, will not init it */
/* CTRL/DATA/ROT open */ bool init(RotatorBase* rot);
bool open(RotatorBase* rot);
/* CTRL/DATA close. Not owning rotator, will not close it */ /* CTRL/DATA close. Not owning rotator, will not close it */
bool close(); bool close();
/* Control APIs */
/* set source using whf, orient and wait flag */
bool setSource(const utils::PipeArgs& args);
/* set crop a.k.a the region of interest */
bool setCrop(const utils::Dim& d);
/* set orientation*/
bool setTransform(const utils::eTransform& param);
/* set mdp posision using dim */
bool setPosition(const utils::Dim& dim);
/* commit changes to the overlay "set"*/ /* commit changes to the overlay "set"*/
bool commit(); bool commit();
/* "Data" related interface */ /* Data APIs */
/* set ID directly to data channel */
void setId(int id);
/* Set FD / memid */
void setMemoryId(int id);
/* queue buffer to the overlay */ /* queue buffer to the overlay */
bool queueBuffer(uint32_t offset); bool queueBuffer(int fd, uint32_t offset);
/* dequeue buffer to the overlay NOTSUPPORTED */
bool dequeueBuffer(void*& buf);
/* wait for vsync to be done */ /* wait for vsync to be done */
bool waitForVsync(); bool waitForVsync();
/* set crop data FIXME setROI (Region Of Intrest) */
bool setCrop(const utils::Dim& d);
/* "Ctrl" related interface */
/*
* Start a session, opens the rotator
* FIXME, we might want to open the rotator separately
*/
bool start(const utils::PipeArgs& args);
/* set mdp posision using dim */
bool setPosition(const utils::Dim& dim);
/* set param using Params (param,value pair) */
bool setParameter(const utils::Params& param);
/* set source using whf, orient and wait flag */
bool setSource(const utils::PipeArgs& args);
/* return cached startup args */ /* return cached startup args */
const utils::PipeArgs& getArgs() const; const utils::PipeArgs& getArgs() const;
@@ -123,33 +96,33 @@ public:
/* dump the state of the object */ /* dump the state of the object */
void dump() const; void dump() const;
private: private:
/* set Closed channel */ /* set Closed pipe */
bool setClosed(); bool setClosed();
// kick off rotator.
bool startRotator();
/* Ctrl/Data aggregator */ /* Ctrl/Data aggregator */
CtrlData mCtrlData; CtrlData mCtrlData;
/* caching startup params. useful when need
* to have the exact copy of that pipe.
* For example when HDMI is connected, and we would
* like to open/start the pipe with the args */
utils::PipeArgs mArgs;
/* rotator mdp base /* rotator mdp base
* Can point to NullRotator or to Rotator*/ * Can point to NullRotator or to Rotator*/
RotatorBase* mRot; RotatorBase* mRot;
/* my flags */ //Whether rotator is used for 0-rot or otherwise
enum { CLOSED = 1<<0 }; bool mRotUsed;
uint32_t mFlags;
/* Pipe open or closed */
enum ePipeState {
CLOSED,
OPEN
};
ePipeState pipeState;
}; };
//------------------------Inlines and Templates ---------------------- //------------------------Inlines and Templates ----------------------
template <int PANEL> template <int PANEL>
GenericPipe<PANEL>::GenericPipe() : mRot(0), mFlags(CLOSED) {} GenericPipe<PANEL>::GenericPipe() : mRot(0), mRotUsed(false),
pipeState(CLOSED) {
}
template <int PANEL> template <int PANEL>
GenericPipe<PANEL>::~GenericPipe() { GenericPipe<PANEL>::~GenericPipe() {
@@ -157,33 +130,42 @@ GenericPipe<PANEL>::~GenericPipe() {
} }
template <int PANEL> template <int PANEL>
bool GenericPipe<PANEL>::open(RotatorBase* rot) bool GenericPipe<PANEL>::init(RotatorBase* rot)
{ {
ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init");
OVASSERT(rot, "rot is null"); OVASSERT(rot, "rot is null");
// open ctrl and data
// init ctrl and data
uint32_t fbnum = utils::getFBForPanel(PANEL); uint32_t fbnum = utils::getFBForPanel(PANEL);
ALOGE_IF(DEBUG_OVERLAY, "GenericPipe open");
if(!mCtrlData.ctrl.open(fbnum, rot)) { if(!mCtrlData.ctrl.init(fbnum)) {
ALOGE("GenericPipe failed to open ctrl"); ALOGE("GenericPipe failed to init ctrl");
return false; return false;
} }
if(!mCtrlData.data.open(fbnum, rot)) {
ALOGE("GenericPipe failed to open data"); if(!mCtrlData.data.init(fbnum)) {
ALOGE("GenericPipe failed to init data");
return false; return false;
} }
//Cache the rot ref. Ownership is with OverlayImpl.
mRot = rot; mRot = rot;
// NOTE: we won't have the flags as non CLOSED since we mRotUsed = false;
// consider the pipe opened for business only when we call
// start() // NOTE:init() on the rot is called by OverlayImpl
// Pipes only have to worry about using rot, and not init or close.
return true; return true;
} }
template <int PANEL> template <int PANEL>
bool GenericPipe<PANEL>::close() { bool GenericPipe<PANEL>::close() {
if(isClosed()) return true; if(isClosed())
return true;
bool ret = true; bool ret = true;
if(!mCtrlData.ctrl.close()) { if(!mCtrlData.ctrl.close()) {
ALOGE("GenericPipe failed to close ctrl"); ALOGE("GenericPipe failed to close ctrl");
ret = false; ret = false;
@@ -192,153 +174,118 @@ bool GenericPipe<PANEL>::close() {
ALOGE("GenericPipe failed to close data"); ALOGE("GenericPipe failed to close data");
ret = false; ret = false;
} }
// NOTE:close() on the rot is called by OverlayImpl
// Pipes only have to worry about using rot, and not init or close.
setClosed(); setClosed();
return ret; return ret;
} }
template <int PANEL> template <int PANEL>
inline bool GenericPipe<PANEL>::commit(){ inline bool GenericPipe<PANEL>::setSource(
OVASSERT(isOpen(), "State is closed, cannot commit"); const utils::PipeArgs& args)
return mCtrlData.ctrl.commit(); {
utils::PipeArgs newargs(args);
//Interlace video handling.
if(newargs.whf.format & INTERLACE_MASK) {
setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE);
}
utils::Whf whf(newargs.whf);
//Extract HAL format from lower bytes. Deinterlace if interlaced.
whf.format = utils::getColorFormat(whf.format);
//Get MDP equivalent of HAL format.
whf.format = utils::getMdpFormat(whf.format);
newargs.whf = whf;
//Cache if user wants 0-rotation
mRotUsed = newargs.rotFlags & utils::ROT_FLAG_ENABLED;
mRot->setSource(newargs.whf);
mRot->setFlags(newargs.mdpFlags);
return mCtrlData.ctrl.setSource(newargs);
} }
template <int PANEL> template <int PANEL>
inline void GenericPipe<PANEL>::setMemoryId(int id) { inline bool GenericPipe<PANEL>::setCrop(
OVASSERT(isOpen(), "State is closed, cannot setMemoryId"); const overlay::utils::Dim& d) {
mCtrlData.data.setMemoryId(id); return mCtrlData.ctrl.setCrop(d);
} }
template <int PANEL> template <int PANEL>
inline void GenericPipe<PANEL>::setId(int id) { inline bool GenericPipe<PANEL>::setTransform(
mCtrlData.data.setId(id); } const utils::eTransform& orient)
{
//Rotation could be enabled by user for zero-rot or the layer could have
//some transform. Mark rotation enabled in either case.
mRotUsed |= (orient != utils::OVERLAY_TRANSFORM_0);
mRot->setTransform(orient, mRotUsed);
return mCtrlData.ctrl.setTransform(orient, mRotUsed);
}
template <int PANEL>
inline bool GenericPipe<PANEL>::setPosition(const utils::Dim& d)
{
return mCtrlData.ctrl.setPosition(d);
}
template <int PANEL>
inline bool GenericPipe<PANEL>::commit() {
bool ret = false;
//If wanting to use rotator, start it.
if(mRotUsed) {
if(!mRot->commit()) {
ALOGE("GenPipe Rotator commit failed");
return false;
}
}
ret = mCtrlData.ctrl.commit();
pipeState = ret ? OPEN : CLOSED;
return ret;
}
template <int PANEL>
inline bool GenericPipe<PANEL>::queueBuffer(int fd, uint32_t offset) {
//TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private.
OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
int pipeId = mCtrlData.ctrl.getPipeId();
OVASSERT(-1 != pipeId, "Ctrl ID should not be -1");
// set pipe id from ctrl to data
mCtrlData.data.setPipeId(pipeId);
int finalFd = fd;
uint32_t finalOffset = offset;
//If rotator is to be used, queue to it, so it can ROTATE.
if(mRotUsed) {
if(!mRot->queueBuffer(fd, offset)) {
ALOGE("GenPipe Rotator play failed");
return false;
}
//Configure MDP's source buffer as the current output buffer of rotator
if(mRot->getDstMemId() != -1) {
finalFd = mRot->getDstMemId();
finalOffset = mRot->getDstOffset();
} else {
//Could be -1 for NullRotator, if queue above succeeds.
//Need an actual rotator. Modify overlay State Traits.
//Not fatal, keep queuing to MDP without rotation.
ALOGE("Null rotator in use, where an actual is required");
}
}
return mCtrlData.data.queueBuffer(finalFd, finalOffset);
}
template <int PANEL> template <int PANEL>
inline int GenericPipe<PANEL>::getCtrlFd() const { inline int GenericPipe<PANEL>::getCtrlFd() const {
return mCtrlData.ctrl.getFd(); return mCtrlData.ctrl.getFd();
} }
template <int PANEL>
inline bool GenericPipe<PANEL>::setCrop(
const overlay::utils::Dim& d) {
OVASSERT(isOpen(), "State is closed, cannot setCrop");
return mCtrlData.ctrl.setCrop(d);
}
template <int PANEL>
bool GenericPipe<PANEL>::start(const utils::PipeArgs& args)
{
/* open before your start control rotator */
uint32_t sz = args.whf.size; //utils::getSizeByMdp(args.whf);
OVASSERT(sz, "GenericPipe sz=%d", sz);
if(!mRot->open()) {
ALOGE("GenericPipe start failed to open rot");
return false;
}
if(!mCtrlData.ctrl.start(args)){
ALOGE("GenericPipe failed to start");
return false;
}
int ctrlId = mCtrlData.ctrl.getId();
OVASSERT(-1 != ctrlId, "Ctrl ID should not be -1");
// set ID requeset to assoc ctrl to data
setId(ctrlId);
// set ID request to assoc MDP data to ROT MDP data
mRot->setDataReqId(mCtrlData.data.getId());
// cache the args for future reference.
mArgs = args;
// we got here so we are open+start and good to go
mFlags = 0; // clear flags from CLOSED
// TODO make it more robust when more flags
// are added
return true;
}
template <int PANEL>
inline const utils::PipeArgs& GenericPipe<PANEL>::getArgs() const
{
return mArgs;
}
template <int PANEL>
bool GenericPipe<PANEL>::startRotator() {
// kick off rotator
if(!mRot->start()) {
ALOGE("GenericPipe failed to start rotator");
return false;
}
return true;
}
template <int PANEL>
inline bool GenericPipe<PANEL>::queueBuffer(uint32_t offset) {
OVASSERT(isOpen(), "State is closed, cannot queueBuffer");
return mCtrlData.data.queueBuffer(offset);
}
template <int PANEL>
inline bool GenericPipe<PANEL>::dequeueBuffer(void*&) {
OVASSERT(isOpen(), "State is closed, cannot dequeueBuffer");
// can also set error to NOTSUPPORTED in the future
return false;
}
template <int PANEL> template <int PANEL>
inline bool GenericPipe<PANEL>::waitForVsync() { inline bool GenericPipe<PANEL>::waitForVsync() {
OVASSERT(isOpen(), "State is closed, cannot waitForVsync"); OVASSERT(isOpen(), "State is closed, cannot waitForVsync");
return mCtrlData.data.waitForVsync(); return mCtrlData.data.waitForVsync();
} }
template <int PANEL>
inline bool GenericPipe<PANEL>::setPosition(const utils::Dim& dim)
{
OVASSERT(isOpen(), "State is closed, cannot setPosition");
return mCtrlData.ctrl.setPosition(dim);
}
template <int PANEL>
inline bool GenericPipe<PANEL>::setParameter(
const utils::Params& param)
{
OVASSERT(isOpen(), "State is closed, cannot setParameter");
// Currently setParameter would start rotator
if(!mCtrlData.ctrl.setParameter(param)) {
ALOGE("GenericPipe failed to setparam");
return false;
}
// if rot flags are ENABLED it means we would always
// like to have rot. Even with 0 rot. (solves tearing)
if(utils::ROT_FLAG_ENABLED == mArgs.rotFlags) {
mRot->setEnable();
}
return startRotator();
}
template <int PANEL>
inline bool GenericPipe<PANEL>::setSource(
const utils::PipeArgs& args)
{
// cache the recent args.
mArgs = args;
// setSource is the 1st thing that is being called on a pipe.
// If pipe is closed, we should start everything.
// we assume it is being opened with the correct FDs.
if(isClosed()) {
if(!this->start(args)) {
ALOGE("GenericPipe setSource failed to start");
return false;
}
return true;
}
return mCtrlData.ctrl.setSource(args);
}
template <int PANEL> template <int PANEL>
inline utils::Dim GenericPipe<PANEL>::getAspectRatio( inline utils::Dim GenericPipe<PANEL>::getAspectRatio(
const utils::Whf& whf) const const utils::Whf& whf) const
@@ -374,7 +321,7 @@ template <int PANEL>
void GenericPipe<PANEL>::dump() const void GenericPipe<PANEL>::dump() const
{ {
ALOGE("== Dump Generic pipe start =="); ALOGE("== Dump Generic pipe start ==");
ALOGE("flags=0x%x", mFlags); ALOGE("pipe state = %d", (int)pipeState);
OVASSERT(mRot, "GenericPipe should have a valid Rot"); OVASSERT(mRot, "GenericPipe should have a valid Rot");
mCtrlData.ctrl.dump(); mCtrlData.ctrl.dump();
mCtrlData.data.dump(); mCtrlData.data.dump();
@@ -384,20 +331,20 @@ void GenericPipe<PANEL>::dump() const
template <int PANEL> template <int PANEL>
inline bool GenericPipe<PANEL>::isClosed() const { inline bool GenericPipe<PANEL>::isClosed() const {
return utils::getBit(mFlags, CLOSED); return (pipeState == CLOSED);
} }
template <int PANEL> template <int PANEL>
inline bool GenericPipe<PANEL>::isOpen() const { inline bool GenericPipe<PANEL>::isOpen() const {
return !isClosed(); return (pipeState == OPEN);
} }
template <int PANEL> template <int PANEL>
inline bool GenericPipe<PANEL>::setClosed() { inline bool GenericPipe<PANEL>::setClosed() {
return utils::setBit(mFlags, CLOSED); pipeState = CLOSED;
return true;
} }
} //namespace overlay } //namespace overlay
#endif // OVERLAY_GENERIC_PIPE_H #endif // OVERLAY_GENERIC_PIPE_H

View File

@@ -46,74 +46,61 @@ public:
/* Please look at overlayGenPipe.h for info */ /* Please look at overlayGenPipe.h for info */
explicit UIMirrorPipe(); explicit UIMirrorPipe();
~UIMirrorPipe(); ~UIMirrorPipe();
bool open(RotatorBase* rot); bool init(RotatorBase* rot);
bool close(); bool close();
bool commit(); bool commit();
void setId(int id); bool queueBuffer(int fd, uint32_t offset);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync(); bool waitForVsync();
bool setCrop(const utils::Dim& dim); bool setCrop(const utils::Dim& dim);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim); bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param); bool setTransform(const utils::eTransform& param);
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const; utils::eOverlayPipeType getOvPipeType() const;
void dump() const; void dump() const;
private: private:
overlay::GenericPipe<ovutils::EXTERNAL> mUI; overlay::GenericPipe<ovutils::EXTERNAL> mUI;
utils::eTransform mPrimFBOr; //Primary FB's orientation
}; };
//----------------------------Inlines ----------------------------- //----------------------------Inlines -----------------------------
inline UIMirrorPipe::UIMirrorPipe() {} inline UIMirrorPipe::UIMirrorPipe() { mPrimFBOr = utils::OVERLAY_TRANSFORM_0; }
inline UIMirrorPipe::~UIMirrorPipe() { close(); } inline UIMirrorPipe::~UIMirrorPipe() { close(); }
inline bool UIMirrorPipe::open(RotatorBase* rot) { inline bool UIMirrorPipe::init(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "UIMirrorPipe open"); ALOGE_IF(DEBUG_OVERLAY, "UIMirrorPipe init");
bool ret = mUI.open(rot); bool ret = mUI.init(rot);
//If source to rotator is framebuffer, which is the case we UI Mirror pipe, //If source to rotator is FB, which is the case with UI Mirror pipe,
//we need to inform driver during playback. Since FB does not use ION. //we need to inform driver during playback, since FB does not use ION.
rot->setSrcFB(true); rot->setSrcFB();
return ret; return ret;
} }
inline bool UIMirrorPipe::close() { return mUI.close(); } inline bool UIMirrorPipe::close() { return mUI.close(); }
inline bool UIMirrorPipe::commit() { return mUI.commit(); } inline bool UIMirrorPipe::commit() { return mUI.commit(); }
inline void UIMirrorPipe::setId(int id) { mUI.setId(id); } inline bool UIMirrorPipe::queueBuffer(int fd, uint32_t offset) {
inline void UIMirrorPipe::setMemoryId(int id) { mUI.setMemoryId(id); } return mUI.queueBuffer(fd, offset);
inline bool UIMirrorPipe::queueBuffer(uint32_t offset) { }
return mUI.queueBuffer(offset); }
inline bool UIMirrorPipe::dequeueBuffer(void*& buf) {
return mUI.dequeueBuffer(buf); }
inline bool UIMirrorPipe::waitForVsync() { inline bool UIMirrorPipe::waitForVsync() {
return mUI.waitForVsync(); } return mUI.waitForVsync(); }
inline bool UIMirrorPipe::setCrop(const utils::Dim& dim) { inline bool UIMirrorPipe::setCrop(const utils::Dim& dim) {
return mUI.setCrop(dim); } return mUI.setCrop(dim); }
inline bool UIMirrorPipe::start(const utils::PipeArgs& args) {
if(!mUI.start(args)) {
ALOGE("%s failed to start", __FUNCTION__);
return false;
}
return true;
}
inline bool UIMirrorPipe::setPosition(const utils::Dim& dim) {
inline bool UIMirrorPipe::setPosition(const utils::Dim& dim) {
ovutils::Dim pdim; ovutils::Dim pdim;
switch (dim.o) { //using utils::eTransform;
case 0: switch (mPrimFBOr) {
case HAL_TRANSFORM_ROT_180: case utils::OVERLAY_TRANSFORM_0:
case utils::OVERLAY_TRANSFORM_ROT_180:
{ {
ovutils::Whf whf(dim.x, dim.y, 0); ovutils::Whf whf(dim.w, dim.h, 0);
pdim = mUI.getAspectRatio(whf); pdim = mUI.getAspectRatio(whf);
break; break;
} }
case HAL_TRANSFORM_ROT_90: case utils::OVERLAY_TRANSFORM_ROT_90:
case HAL_TRANSFORM_ROT_270: case utils::OVERLAY_TRANSFORM_ROT_270:
{ {
// Calculate the Aspectratio for the UI in the landscape mode // Calculate the Aspectratio for the UI in the landscape mode
// Width and height will be swapped as there is rotation // Width and height will be swapped as there is rotation
ovutils::Whf whf(dim.y, dim.x, 0); ovutils::Whf whf(dim.h, dim.w, 0);
pdim = mUI.getAspectRatio(whf); pdim = mUI.getAspectRatio(whf);
break; break;
} }
@@ -121,43 +108,43 @@ inline bool UIMirrorPipe::setPosition(const utils::Dim& dim) {
ALOGE("%s: Unknown orientation %d", __FUNCTION__, dim.o); ALOGE("%s: Unknown orientation %d", __FUNCTION__, dim.o);
return false; return false;
} }
ovutils::even_out(pdim.x);
ovutils::even_out(pdim.y);
ovutils::even_out(pdim.w);
ovutils::even_out(pdim.h);
return mUI.setPosition(pdim); return mUI.setPosition(pdim);
} }
inline bool UIMirrorPipe::setParameter(const utils::Params& param) {
OVASSERT(utils::OVERLAY_TRANSFORM_UI == param.param, inline bool UIMirrorPipe::setTransform(const utils::eTransform& param) {
"%p Expecting OVERLAY_TRANSFORM_UI", __FUNCTION__);
int orientation = param.value; //Cache the primary FB orientation, since the TV's will be 0, we need this
//info to translate later.
mPrimFBOr = param;
utils::eTransform transform = param;
// Figure out orientation to transform to // Figure out orientation to transform to
switch (param.value) { switch (param) {
case 0: case utils::OVERLAY_TRANSFORM_0:
orientation = 0; transform = utils::OVERLAY_TRANSFORM_0;
break; break;
case HAL_TRANSFORM_ROT_180: case utils::OVERLAY_TRANSFORM_ROT_180:
orientation = HAL_TRANSFORM_ROT_180; //If prim FB is drawn 180 rotated, rotate by additional 180 to make
//it to 0, which is TV's orientation.
transform = utils::OVERLAY_TRANSFORM_ROT_180;
break; break;
case HAL_TRANSFORM_ROT_90: case utils::OVERLAY_TRANSFORM_ROT_90:
orientation = HAL_TRANSFORM_ROT_270; //If prim FB is drawn 90 rotated, rotate by additional 270 to make
//it to 0, which is TV's orientation.
transform = utils::OVERLAY_TRANSFORM_ROT_270;
break; break;
case HAL_TRANSFORM_ROT_270: case utils::OVERLAY_TRANSFORM_ROT_270:
orientation = HAL_TRANSFORM_ROT_90; //If prim FB is drawn 270 rotated, rotate by additional 90 to make
//it to 0, which is TV's orientation.
transform = utils::OVERLAY_TRANSFORM_ROT_90;
break; break;
default: default:
ALOGE("%s: Unknown orientation %d", __FUNCTION__, param.value); ALOGE("%s: Unknown orientation %d", __FUNCTION__,
static_cast<int>(param));
return false; return false;
} }
ovutils::eTransform transform = return mUI.setTransform(transform);
static_cast<ovutils::eTransform>(orientation);
const ovutils::Params prms (ovutils::OVERLAY_TRANSFORM, transform);
return mUI.setParameter(prms);
} }
inline bool UIMirrorPipe::setSource(const utils::PipeArgs& args) { inline bool UIMirrorPipe::setSource(const utils::PipeArgs& args) {
@@ -175,9 +162,6 @@ inline bool UIMirrorPipe::setSource(const utils::PipeArgs& args) {
return mUI.setSource(arg); return mUI.setSource(arg);
} }
inline const utils::PipeArgs& UIMirrorPipe::getArgs() const {
return mUI.getArgs();
}
inline utils::eOverlayPipeType UIMirrorPipe::getOvPipeType() const { inline utils::eOverlayPipeType UIMirrorPipe::getOvPipeType() const {
return utils::OV_PIPE_TYPE_UI_MIRROR; return utils::OV_PIPE_TYPE_UI_MIRROR;
} }

View File

@@ -27,8 +27,8 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef OVERLAY_HDMI_PIPE_H #ifndef OVERLAY_VIDEO_EXT_PIPE_H
#define OVERLAY_HDMI_PIPE_H #define OVERLAY_VIDEO_EXT_PIPE_H
#include "overlayGenPipe.h" #include "overlayGenPipe.h"
#include "overlayUtils.h" #include "overlayUtils.h"
@@ -41,88 +41,79 @@ namespace overlay {
/* A specific impl of GenericPipe /* A specific impl of GenericPipe
* Whenever needed to have a pass through - we do it. * Whenever needed to have a pass through - we do it.
* If there is a special need for a different behavior - do it here */ * If there is a special need for a different behavior - do it here */
class HdmiPipe : utils::NoCopy { class VideoExtPipe : utils::NoCopy {
public: public:
/* Please look at overlayGenPipe.h for info */ /* Please look at overlayGenPipe.h for info */
explicit HdmiPipe(); explicit VideoExtPipe();
~HdmiPipe(); ~VideoExtPipe();
bool open(RotatorBase* rot); bool init(RotatorBase* rot);
bool close(); bool close();
bool commit(); bool commit();
void setId(int id); bool queueBuffer(int fd, uint32_t offset);
void setMemoryId(int id);
bool queueBuffer(uint32_t offset);
bool dequeueBuffer(void*& buf);
bool waitForVsync(); bool waitForVsync();
bool setCrop(const utils::Dim& dim); bool setCrop(const utils::Dim& dim);
bool start(const utils::PipeArgs& args);
bool setPosition(const utils::Dim& dim); bool setPosition(const utils::Dim& dim);
bool setParameter(const utils::Params& param); bool setTransform(const utils::eTransform& param);
bool setSource(const utils::PipeArgs& args); bool setSource(const utils::PipeArgs& args);
const utils::PipeArgs& getArgs() const;
utils::eOverlayPipeType getOvPipeType() const; utils::eOverlayPipeType getOvPipeType() const;
void dump() const; void dump() const;
private: private:
overlay::GenericPipe<ovutils::EXTERNAL> mHdmi; overlay::GenericPipe<ovutils::EXTERNAL> mVideoExt;
}; };
//------------------Inlines ----------------------------- //------------------Inlines -----------------------------
inline HdmiPipe::HdmiPipe() {} inline VideoExtPipe::VideoExtPipe() {}
inline HdmiPipe::~HdmiPipe() { close(); } inline VideoExtPipe::~VideoExtPipe() { close(); }
inline bool HdmiPipe::open(RotatorBase* rot) { inline bool VideoExtPipe::init(RotatorBase* rot) {
ALOGE_IF(DEBUG_OVERLAY, "HdmiPipe open"); ALOGE_IF(DEBUG_OVERLAY, "VideoExtPipe init");
return mHdmi.open(rot); return mVideoExt.init(rot);
} }
inline bool HdmiPipe::close() { return mHdmi.close(); } inline bool VideoExtPipe::close() { return mVideoExt.close(); }
inline bool HdmiPipe::commit() { return mHdmi.commit(); } inline bool VideoExtPipe::commit() { return mVideoExt.commit(); }
inline void HdmiPipe::setId(int id) { mHdmi.setId(id); } inline bool VideoExtPipe::queueBuffer(int fd, uint32_t offset) {
inline void HdmiPipe::setMemoryId(int id) { mHdmi.setMemoryId(id); } return mVideoExt.queueBuffer(fd, offset);
inline bool HdmiPipe::queueBuffer(uint32_t offset) { }
return mHdmi.queueBuffer(offset); } inline bool VideoExtPipe::waitForVsync() {
inline bool HdmiPipe::dequeueBuffer(void*& buf) { return mVideoExt.waitForVsync();
return mHdmi.dequeueBuffer(buf); } }
inline bool HdmiPipe::waitForVsync() { inline bool VideoExtPipe::setCrop(const utils::Dim& dim) {
return mHdmi.waitForVsync(); } return mVideoExt.setCrop(dim);
inline bool HdmiPipe::setCrop(const utils::Dim& dim) { }
return mHdmi.setCrop(dim); } inline bool VideoExtPipe::setPosition(const utils::Dim& dim)
inline bool HdmiPipe::start(const utils::PipeArgs& args) {
return mHdmi.start(args); }
inline bool HdmiPipe::setPosition(const utils::Dim& dim)
{ {
utils::Dim d; utils::Dim d;
// Need to change dim to aspect ratio // Need to change dim to aspect ratio
if (utils::FrameBufferInfo::getInstance()->supportTrueMirroring()) { if (utils::FrameBufferInfo::getInstance()->supportTrueMirroring()) {
// Use dim info to calculate aspect ratio for true UI mirroring // Use dim info to calculate aspect ratio for true UI mirroring
d = mHdmi.getAspectRatio(dim); d = mVideoExt.getAspectRatio(dim);
} else { } else {
// Use cached crop data to get aspect ratio // Use cached crop data to get aspect ratio
utils::Dim crop = mHdmi.getCrop(); utils::Dim crop = mVideoExt.getCrop();
utils::Whf whf(crop.w, crop.h, 0); utils::Whf whf(crop.w, crop.h, 0);
d = mHdmi.getAspectRatio(whf); d = mVideoExt.getAspectRatio(whf);
} }
ALOGE_IF(DEBUG_OVERLAY, "Calculated aspect ratio for HDMI: x=%d, y=%d, w=%d, h=%d, o=%d", ALOGE_IF(DEBUG_OVERLAY, "Calculated aspect ratio for EXT: x=%d, y=%d, w=%d,"
"h=%d, o=%d",
d.x, d.y, d.w, d.h, d.o); d.x, d.y, d.w, d.h, d.o);
return mHdmi.setPosition(d); return mVideoExt.setPosition(d);
} }
inline bool HdmiPipe::setParameter(const utils::Params& param) { inline bool VideoExtPipe::setTransform(const utils::eTransform& param) {
return mHdmi.setParameter(param); } return mVideoExt.setTransform(param);
inline bool HdmiPipe::setSource(const utils::PipeArgs& args) { }
inline bool VideoExtPipe::setSource(const utils::PipeArgs& args) {
utils::PipeArgs arg(args); utils::PipeArgs arg(args);
return mHdmi.setSource(arg); return mVideoExt.setSource(arg);
} }
inline const utils::PipeArgs& HdmiPipe::getArgs() const { inline utils::eOverlayPipeType VideoExtPipe::getOvPipeType() const {
return mHdmi.getArgs(); return utils::OV_PIPE_TYPE_VIDEO_EXT;
} }
inline utils::eOverlayPipeType HdmiPipe::getOvPipeType() const { inline void VideoExtPipe::dump() const {
return utils::OV_PIPE_TYPE_HDMI; ALOGE("Video Ext Pipe");
} mVideoExt.dump();
inline void HdmiPipe::dump() const {
ALOGE("HDMI Pipe");
mHdmi.dump();
} }
} // overlay } // overlay
#endif // OVERLAY_HDMI_PIPE_H #endif // OVERLAY_VIDEO_EXT_PIPE_H