1/* 2// Copyright (c) 2014 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16#include <HwcTrace.h> 17#include <tangier/TngPlaneManager.h> 18#include <tangier/TngPrimaryPlane.h> 19#include <tangier/TngSpritePlane.h> 20#include <tangier/TngOverlayPlane.h> 21#include <tangier/TngCursorPlane.h> 22 23namespace android { 24namespace intel { 25 26TngPlaneManager::TngPlaneManager() 27 : DisplayPlaneManager() 28{ 29 memset(&mZorder, 0, sizeof(mZorder)); 30} 31 32TngPlaneManager::~TngPlaneManager() 33{ 34} 35 36bool TngPlaneManager::initialize() 37{ 38 mSpritePlaneCount = 1; // Sprite D 39 mOverlayPlaneCount = 2; // Overlay A & C 40 mPrimaryPlaneCount = 3; // Primary A, B, C 41 mCursorPlaneCount = 3; 42 43 return DisplayPlaneManager::initialize(); 44} 45 46void TngPlaneManager::deinitialize() 47{ 48 DisplayPlaneManager::deinitialize(); 49} 50 51DisplayPlane* TngPlaneManager::allocPlane(int index, int type) 52{ 53 DisplayPlane *plane = 0; 54 55 switch (type) { 56 case DisplayPlane::PLANE_PRIMARY: 57 plane = new TngPrimaryPlane(index, index); 58 break; 59 case DisplayPlane::PLANE_SPRITE: 60 plane = new TngSpritePlane(index, 0); 61 break; 62 case DisplayPlane::PLANE_OVERLAY: 63 plane = new TngOverlayPlane(index, 0); 64 break; 65 case DisplayPlane::PLANE_CURSOR: 66 plane = new TngCursorPlane(index, index /*disp */); 67 break; 68 default: 69 ETRACE("unsupported type %d", type); 70 break; 71 } 72 if (plane && !plane->initialize(DisplayPlane::MIN_DATA_BUFFER_COUNT)) { 73 ETRACE("failed to initialize plane."); 74 DEINIT_AND_DELETE_OBJ(plane); 75 } 76 77 return plane; 78} 79 80bool TngPlaneManager::isValidZOrder(int dsp, ZOrderConfig& config) 81{ 82 // check whether it's a supported z order config 83 int firstRGB = -1; 84 int lastRGB = -1; 85 int firstOverlay = -1; 86 int lastOverlay = -1; 87 88 for (int i = 0; i < (int)config.size(); i++) { 89 const ZOrderLayer *layer = config[i]; 90 switch (layer->planeType) { 91 case DisplayPlane::PLANE_PRIMARY: 92 case DisplayPlane::PLANE_SPRITE: 93 if (firstRGB == -1) { 94 firstRGB = i; 95 lastRGB = i; 96 } else { 97 lastRGB = i; 98 } 99 break; 100 case DisplayPlane::PLANE_OVERLAY: 101 case DisplayPlane::PLANE_CURSOR: 102 if (firstOverlay == -1) { 103 firstOverlay = i; 104 lastOverlay = i; 105 } else { 106 lastOverlay = i; 107 } 108 break; 109 } 110 } 111 112 if ((lastRGB < firstOverlay) || (firstRGB > lastOverlay)) { 113 return true; 114 } else { 115 VTRACE("invalid z order config. rgb (%d, %d) yuv (%d, %d)", 116 firstRGB, lastRGB, firstOverlay, lastOverlay); 117 return false; 118 } 119} 120 121bool TngPlaneManager::assignPlanes(int dsp, ZOrderConfig& config) 122{ 123 // probe if plane is available 124 int size = (int)config.size(); 125 for (int i = 0; i < size; i++) { 126 const ZOrderLayer *layer = config.itemAt(i); 127 if (!getFreePlanes(dsp, layer->planeType)) { 128 DTRACE("no plane available for dsp %d, type %d", dsp, layer->planeType); 129 return false; 130 } 131 } 132 133 if (config.size() == 1 && config[0]->planeType == DisplayPlane::PLANE_SPRITE) { 134 config[0]->planeType == DisplayPlane::PLANE_PRIMARY; 135 } 136 137 // allocate planes 138 for (int i = 0; i < size; i++) { 139 ZOrderLayer *layer = config.itemAt(i); 140 layer->plane = getPlaneHelper(dsp, layer->planeType); 141 if (layer->plane == NULL) { 142 // should never happen!! 143 ETRACE("failed to assign plane for type %d", layer->planeType); 144 return false; 145 } 146 // sequence !!!!! enabling plane before setting zorder 147 // see TngSpritePlane::enablePlane implementation!!!! 148 layer->plane->enable(); 149 } 150 151 // setup Z order 152 for (int i = 0; i < size; i++) { 153 ZOrderLayer *layer = config.itemAt(i); 154 layer->plane->setZOrderConfig(config, &mZorder); 155 } 156 157 return true; 158} 159 160void* TngPlaneManager::getZOrderConfig() const 161{ 162 return (void*)&mZorder; 163} 164 165DisplayPlane* TngPlaneManager::getPlaneHelper(int dsp, int type) 166{ 167 RETURN_NULL_IF_NOT_INIT(); 168 169 if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) { 170 ETRACE("Invalid display device %d", dsp); 171 return 0; 172 } 173 174 int index = dsp == IDisplayDevice::DEVICE_PRIMARY ? 0 : 1; 175 176 if (type == DisplayPlane::PLANE_PRIMARY || 177 type == DisplayPlane::PLANE_CURSOR) { 178 return getPlane(type, index); 179 } else if (type == DisplayPlane::PLANE_SPRITE) { 180 return getAnyPlane(type); 181 } else if (type == DisplayPlane::PLANE_OVERLAY) { 182 // use overlay A for pipe A and overlay C for pipe B if possible 183 DisplayPlane *plane = getPlane(type, index); 184 if (plane == NULL) { 185 plane = getPlane(type, !index); 186 } 187 return plane; 188 } else { 189 ETRACE("invalid plane type %d", type); 190 return 0; 191 } 192} 193 194} // namespace intel 195} // namespace android 196 197