/* // 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