|
|
/* |
|
|
// Copyright (c) 2014 Intel Corporation |
|
|
// |
|
|
// 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 <HwcTrace.h> |
|
|
#include <tangier/TngPlaneManager.h> |
|
|
#include <tangier/TngPrimaryPlane.h> |
|
|
#include <tangier/TngSpritePlane.h> |
|
|
#include <tangier/TngOverlayPlane.h> |
|
|
#include <tangier/TngCursorPlane.h> |
|
|
|
|
|
namespace android { |
|
|
namespace intel { |
|
|
|
|
|
TngPlaneManager::TngPlaneManager() |
|
|
: DisplayPlaneManager() |
|
|
{ |
|
|
memset(&mZorder, 0, sizeof(mZorder)); |
|
|
} |
|
|
|
|
|
TngPlaneManager::~TngPlaneManager() |
|
|
{ |
|
|
} |
|
|
|
|
|
bool TngPlaneManager::initialize() |
|
|
{ |
|
|
mSpritePlaneCount = 1; // Sprite D |
|
|
mOverlayPlaneCount = 0; // Skip overlay A & C by setting count to 0 |
|
|
mPrimaryPlaneCount = 3; // Primary A, B, C |
|
|
mCursorPlaneCount = 3; |
|
|
|
|
|
return DisplayPlaneManager::initialize(); |
|
|
} |
|
|
|
|
|
void TngPlaneManager::deinitialize() |
|
|
{ |
|
|
DisplayPlaneManager::deinitialize(); |
|
|
} |
|
|
|
|
|
DisplayPlane* TngPlaneManager::allocPlane(int index, int type) |
|
|
{ |
|
|
DisplayPlane *plane = 0; |
|
|
|
|
|
switch (type) { |
|
|
case DisplayPlane::PLANE_PRIMARY: |
|
|
plane = new TngPrimaryPlane(index, index); |
|
|
break; |
|
|
case DisplayPlane::PLANE_SPRITE: |
|
|
plane = new TngSpritePlane(index, 0); |
|
|
break; |
|
|
case DisplayPlane::PLANE_OVERLAY: |
|
|
plane = new TngOverlayPlane(index, 0); |
|
|
break; |
|
|
case DisplayPlane::PLANE_CURSOR: |
|
|
plane = new TngCursorPlane(index, index /*disp */); |
|
|
break; |
|
|
default: |
|
|
ETRACE("unsupported type %d", type); |
|
|
break; |
|
|
} |
|
|
if (plane && !plane->initialize(DisplayPlane::MIN_DATA_BUFFER_COUNT)) { |
|
|
ETRACE("failed to initialize plane."); |
|
|
DEINIT_AND_DELETE_OBJ(plane); |
|
|
} |
|
|
|
|
|
return plane; |
|
|
} |
|
|
|
|
|
bool TngPlaneManager::isValidZOrder(int dsp, ZOrderConfig& config) |
|
|
{ |
|
|
// check whether it's a supported z order config |
|
|
int firstRGB = -1; |
|
|
int lastRGB = -1; |
|
|
int firstOverlay = -1; |
|
|
int lastOverlay = -1; |
|
|
|
|
|
for (int i = 0; i < (int)config.size(); i++) { |
|
|
const ZOrderLayer *layer = config[i]; |
|
|
switch (layer->planeType) { |
|
|
case DisplayPlane::PLANE_PRIMARY: |
|
|
case DisplayPlane::PLANE_SPRITE: |
|
|
if (firstRGB == -1) { |
|
|
firstRGB = i; |
|
|
lastRGB = i; |
|
|
} else { |
|
|
lastRGB = i; |
|
|
} |
|
|
break; |
|
|
case DisplayPlane::PLANE_OVERLAY: |
|
|
case DisplayPlane::PLANE_CURSOR: |
|
|
if (firstOverlay == -1) { |
|
|
firstOverlay = i; |
|
|
lastOverlay = i; |
|
|
} else { |
|
|
lastOverlay = i; |
|
|
} |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
if ((lastRGB < firstOverlay) || (firstRGB > lastOverlay)) { |
|
|
return true; |
|
|
} else { |
|
|
VTRACE("invalid z order config. rgb (%d, %d) yuv (%d, %d)", |
|
|
firstRGB, lastRGB, firstOverlay, lastOverlay); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
bool TngPlaneManager::assignPlanes(int dsp, ZOrderConfig& config) |
|
|
{ |
|
|
// probe if plane is available |
|
|
int size = (int)config.size(); |
|
|
for (int i = 0; i < size; i++) { |
|
|
const ZOrderLayer *layer = config.itemAt(i); |
|
|
if (!getFreePlanes(dsp, layer->planeType)) { |
|
|
DTRACE("no plane available for dsp %d, type %d", dsp, layer->planeType); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
if (config.size() == 1 && config[0]->planeType == DisplayPlane::PLANE_SPRITE) { |
|
|
config[0]->planeType == DisplayPlane::PLANE_PRIMARY; |
|
|
} |
|
|
|
|
|
// allocate planes |
|
|
for (int i = 0; i < size; i++) { |
|
|
ZOrderLayer *layer = config.itemAt(i); |
|
|
layer->plane = getPlaneHelper(dsp, layer->planeType); |
|
|
if (layer->plane == NULL) { |
|
|
// should never happen!! |
|
|
ETRACE("failed to assign plane for type %d", layer->planeType); |
|
|
return false; |
|
|
} |
|
|
// sequence !!!!! enabling plane before setting zorder |
|
|
// see TngSpritePlane::enablePlane implementation!!!! |
|
|
layer->plane->enable(); |
|
|
} |
|
|
|
|
|
// setup Z order |
|
|
for (int i = 0; i < size; i++) { |
|
|
ZOrderLayer *layer = config.itemAt(i); |
|
|
layer->plane->setZOrderConfig(config, &mZorder); |
|
|
} |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
void* TngPlaneManager::getZOrderConfig() const |
|
|
{ |
|
|
return (void*)&mZorder; |
|
|
} |
|
|
|
|
|
DisplayPlane* TngPlaneManager::getPlaneHelper(int dsp, int type) |
|
|
{ |
|
|
RETURN_NULL_IF_NOT_INIT(); |
|
|
|
|
|
if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) { |
|
|
ETRACE("Invalid display device %d", dsp); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
int index = dsp == IDisplayDevice::DEVICE_PRIMARY ? 0 : 1; |
|
|
|
|
|
if (type == DisplayPlane::PLANE_PRIMARY || |
|
|
type == DisplayPlane::PLANE_CURSOR) { |
|
|
return getPlane(type, index); |
|
|
} else if (type == DisplayPlane::PLANE_SPRITE) { |
|
|
return getAnyPlane(type); |
|
|
} else if (type == DisplayPlane::PLANE_OVERLAY) { |
|
|
// use overlay A for pipe A and overlay C for pipe B if possible |
|
|
DisplayPlane *plane = getPlane(type, index); |
|
|
if (plane == NULL) { |
|
|
plane = getPlane(type, !index); |
|
|
} |
|
|
return plane; |
|
|
} else { |
|
|
ETRACE("invalid plane type %d", type); |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
} // namespace intel |
|
|
} // namespace android |
|
|
|
|
|
|