LayerBase.cpp revision 78fd5010a87425d2be401d10a306dd68638fc1dd
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 23310f8da0c3122ed5419db8f12a6e98d3188325b2Mathias Agopian#include <binder/IPCThreadState.h> 24310f8da0c3122ed5419db8f12a6e98d3188325b2Mathias Agopian#include <binder/IServiceManager.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/glext.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <hardware/hardware.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBase.h" 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t LayerBase::typeInfo = 1; 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const LayerBase::typeID = "LayerBase"; 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2; 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const LayerBaseClient::typeID = "LayerBaseClient"; 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : dpy(display), contentDirty(false), 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger(flinger), 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransformed(false), 53a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian mUseLinearFiltering(false), 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mOrientation(0), 55ca6fab2b534fc7b252d0ee7ec2079afff7e5c308Mathias Agopian mLeft(0), mTop(0), 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 57d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian mPremultipliedAlpha(true), mDebug(false), 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidate(0) 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlags = hw.getFlags(); 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBase::~LayerBase() 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 68d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopianvoid LayerBase::setName(const String8& name) { 69d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian mName = name; 70d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian} 71d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian 72d12965934712ed0b9c1a264a6934dc0dad839ffdMathias AgopianString8 LayerBase::getName() const { 73d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian return mName; 74d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian} 75d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& LayerBase::graphicPlane(int dpy) const 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlinger->graphicPlane(dpy); 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& LayerBase::graphicPlane(int dpy) 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlinger->graphicPlane(dpy); 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t layerFlags = 0; 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & ISurfaceComposer::eHidden) 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layerFlags = ISurfaceComposer::eLayerHidden; 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & ISurfaceComposer::eNonPremultiplied) 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPremultipliedAlpha = false; 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 957e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.z = 0; 967e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.w = w; 977e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.h = h; 987e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_w = w; 997e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_h = h; 1007e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.alpha = 0xFF; 1017e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.flags = layerFlags; 1027e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.sequence = 0; 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set(0, 0); 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // drawing state & current state are identical 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 109ba6be54876a19444f0b214b4b3b0749df227b013Mathias Agopianvoid LayerBase::commitTransaction() { 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::forceVisibilityTransaction() { 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this can be called without SurfaceFlinger.mStateLock, but if we 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // can atomically increment the sequence number, it doesn't matter. 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&mCurrentState.sequence); 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::requestTransaction() { 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t old = setTransactionFlags(eTransactionNeeded); 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return ((old & eTransactionNeeded) == 0); 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::getTransactionFlags(uint32_t flags) { 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::setTransactionFlags(uint32_t flags) { 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_or(flags, &mTransactionFlags); 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setPosition(int32_t x, int32_t y) { 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set(x, y); 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setLayer(uint32_t z) { 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.z == z) 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.z = z; 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setSize(uint32_t w, uint32_t h) { 1467e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if (mCurrentState.requested_w == w && mCurrentState.requested_h == h) 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 1487e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_w = w; 1497e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_h = h; 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setAlpha(uint8_t alpha) { 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.alpha == alpha) 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.alpha = alpha; 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: check the matrix has changed 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set( 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setTransparentRegionHint(const Region& transparent) { 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: check the region has changed 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transparentRegion = transparent; 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setFlags(uint8_t flags, uint8_t mask) { 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.flags == newFlags) 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.flags = newFlags; 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect LayerBase::visibleBounds() const 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mTransformedBounds; 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::setVisibleRegion(const Region& visibleRegion) { 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // always called from main thread 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegionScreen = visibleRegion; 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::setCoveredRegion(const Region& coveredRegion) { 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // always called from main thread 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project coveredRegionScreen = coveredRegion; 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::doTransaction(uint32_t flags) 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2067e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if ((front.requested_w != temp.requested_w) || 2077e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian (front.requested_h != temp.requested_h)) { 2087e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian // resize the layer, set the physical size to the requested size 2097e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian Layer::State& editTemp(currentState()); 2107e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian editTemp.w = temp.requested_w; 2117e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian editTemp.h = temp.requested_h; 2127e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian } 2136656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian 2146656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian if ((front.w != temp.w) || (front.h != temp.h)) { 2156656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian // invalidate and recompute the visible regions if needed 2166656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian flags |= Layer::eVisibleRegion; 2176656dbc81273424d9b4bf78c42a4e179dbe1cb71Mathias Agopian } 2187e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // invalidate and recompute the visible regions if needed 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eVisibleRegion; 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this->contentDirty = true; 223a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian 224a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian const bool linearFiltering = mUseLinearFiltering; 225a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian mUseLinearFiltering = false; 226a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 227a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian // we may use linear filtering, if the matrix scales us 228a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian const uint8_t type = temp.transform.getType(); 229a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) { 230a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian mUseLinearFiltering = true; 231a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 232a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 233a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 234a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Commit the transaction 236ba6be54876a19444f0b214b4b3b0749df227b013Mathias Agopian commitTransaction(); 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return flags; 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::validateVisibility(const Transform& planeTransform) 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool transformed = tr.transformed(); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 246cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian uint32_t w = s.w; 247cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian uint32_t h = s.h; 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[0], 0, 0); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[1], 0, h); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[2], w, h); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[3], w, 0); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(transformed)) { 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // NOTE: here we could also punt if we have too many rectangles 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in the transparent region 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (tr.preserveRects()) { 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the transparent region 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project transparentRegionScreen = tr.transform(s.transparentRegion); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transformation too complex, can't do the transparent region 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // optimization. 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project transparentRegionScreen.clear(); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project transparentRegionScreen = s.transparentRegion; 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // cache a few things... 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mOrientation = tr.getOrientation(); 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransformedBounds = tr.makeBounds(w, h); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransformed = transformed; 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLeft = tr.tx(); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTop = tr.ty(); 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::unlockPageFlip( 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(visibleRegionScreen); 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::finishPageFlip() 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::invalidate() 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->signalEvent(); 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::drawRegion(const Region& reg) const 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 30020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = reg.begin(); 30120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = reg.end(); 30220f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (it != end) { 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Rect r; 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t fbWidth = hw.getWidth(); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t fbHeight = hw.getHeight(); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { fbWidth, fbHeight }, { 0, fbHeight } }; 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 31020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 31120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = fbHeight - (r.top + r.height()); 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::draw(const Region& inClip) const 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // invalidate the region we'll update 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region clip(inClip); // copy-on-write, so no-op most of the time 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Remove the transparent area from the clipping region 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const State& s = drawingState(); 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!s.transparentRegion.isEmpty())) { 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project clip.subtract(transparentRegionScreen); 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (clip.isEmpty()) { 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // usually this won't happen because this should be taken care of 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // by SurfaceFlinger::computeVisibleRegions() 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // reset GL state 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project onDraw(clip); 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_TEXTURE_2D); 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_BLEND); 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glColor4x(0, 0x8000, 0, 0x10000); 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project drawRegion(transparentRegionScreen); 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGLuint LayerBase::createTexture() const 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLuint textureName = -1; 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &textureName); 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, textureName); 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 358a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 359a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return textureName; 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36329aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavinvoid LayerBase::clearWithOpenGL(const Region& clip, GLclampx red, 36429aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin GLclampx green, GLclampx blue, 36529aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin GLclampx alpha) const 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t fbHeight = hw.getHeight(); 36929aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin glColor4x(red,green,blue,alpha); 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_TEXTURE_2D); 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 37320f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 37420f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = clip.begin(); 37520f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = clip.end(); 37695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glEnable(GL_SCISSOR_TEST); 37778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glVertexPointer(2, GL_FLOAT, 0, mVertices); 37895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian while (it != end) { 37995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const Rect& r = *it++; 38095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const GLint sy = fbHeight - (r.top + r.height()); 38195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 38295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38629aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavinvoid LayerBase::clearWithOpenGL(const Region& clip) const 38729aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin{ 38829aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin clearWithOpenGL(clip,0,0,0,0); 38929aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin} 39029aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin 3911fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopianvoid LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t fbHeight = hw.getHeight(); 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const State& s(drawingState()); 3960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // bind our texture 3981fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian validateTexture(texture.name); 3991fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian uint32_t width = texture.width; 4001fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian uint32_t height = texture.height; 4011fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(s.alpha < 0xFF)) { 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // We have an alpha-modulation. We need to modulate all 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // texture components by alpha because we're always using 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // premultiplied alpha. 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the texture doesn't have an alpha channel we can 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // use REPLACE and switch to non premultiplied alpha 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // blending (SRCA/ONE_MINUS_SRCA). 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLenum env, src; 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (needsBlending()) { 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project env = GL_MODULATE; 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project env = GL_REPLACE; 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project src = GL_SRC_ALPHA; 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 42178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian const GLfloat alpha = s.alpha * (1.0f/255.0f); 42278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glColor4f(alpha, alpha, alpha, alpha); 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_BLEND); 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 42878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glColor4f(1, 1, 1, 1); 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (needsBlending()) { 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_BLEND); 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian Region::const_iterator it = clip.begin(); 43995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian Region::const_iterator const end = clip.end(); 44078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian const GLfloat texCoords[4][2] = { 44178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian { 0, 0 }, 44278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian { 0, 1 }, 44378fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian { 1, 1 }, 44478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian { 1, 0 } 44578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian }; 44678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian 44778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glMatrixMode(GL_TEXTURE); 44878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glLoadIdentity(); 44978fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian 45078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian // the texture's source is rotated 45178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian switch (texture.transform) { 45278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian case HAL_TRANSFORM_ROT_90: 45378fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glTranslatef(0, 1, 0); 45478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glRotatef(-90, 0, 0, 1); 45578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian break; 45678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian case HAL_TRANSFORM_ROT_180: 45778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glTranslatef(1, 1, 0); 45878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glRotatef(-180, 0, 0, 1); 45978fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian break; 46078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian case HAL_TRANSFORM_ROT_270: 46178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glTranslatef(1, 0, 0); 46278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glRotatef(-270, 0, 0, 1); 46378fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian break; 46478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian } 4655994a330ac949e7706540f22cd73d76d9f2a96cbChih-Chung Chang 46678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian if (texture.NPOTAdjust) { 46778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glScalef(texture.wScale, texture.hScale, 1.0f); 46878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian } 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 47178fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glVertexPointer(2, GL_FLOAT, 0, mVertices); 47278fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47478fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian while (it != end) { 47578fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian const Rect& r = *it++; 47678fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian const GLint sy = fbHeight - (r.top + r.height()); 47778fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glScissor(r.left, sy, r.width(), r.height()); 47878fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 48078fd5010a87425d2be401d10a306dd68638fc1ddMathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::validateTexture(GLint textureName) const 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, textureName); 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: reload the texture if needed 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this is currently done in loadTexture() below 488a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian if (mUseLinearFiltering) { 489a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 490a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 491a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } else { 492a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 493a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 494a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 495401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 496401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian if (needsDithering()) { 497401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian glEnable(GL_DITHER); 498401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian } else { 499401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian glDisable(GL_DITHER); 500401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian } 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 50354ed4f6282bdea251455f39b978626026affdbefMathias Agopianbool LayerBase::isSupportedYuvFormat(int format) const 50454ed4f6282bdea251455f39b978626026affdbefMathias Agopian{ 50554ed4f6282bdea251455f39b978626026affdbefMathias Agopian switch (format) { 50654ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 50754ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_420_SP: 50854ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_P: 50954ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_420_P: 51054ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 51154ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCbCr_420_I: 51254ed4f6282bdea251455f39b978626026affdbefMathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 51354ed4f6282bdea251455f39b978626026affdbefMathias Agopian return true; 51454ed4f6282bdea251455f39b978626026affdbefMathias Agopian } 51554ed4f6282bdea251455f39b978626026affdbefMathias Agopian return false; 51654ed4f6282bdea251455f39b978626026affdbefMathias Agopian} 51754ed4f6282bdea251455f39b978626026affdbefMathias Agopian 5183330b203039dea366d4981db1408a460134b2d2cMathias Agopianvoid LayerBase::loadTexture(Texture* texture, 5191fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian const Region& dirty, const GGLSurface& t) const 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 5213330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (texture->name == -1U) { 5223330b203039dea366d4981db1408a460134b2d2cMathias Agopian // uh? 5233330b203039dea366d4981db1408a460134b2d2cMathias Agopian return; 5243330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 52557720c384af81327d327ef8b88078f11a750fd05Mathias Agopian 5263330b203039dea366d4981db1408a460134b2d2cMathias Agopian glBindTexture(GL_TEXTURE_2D, texture->name); 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * In OpenGL ES we can't specify a stride with glTexImage2D (however, 530076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * GL_UNPACK_ALIGNMENT is a limited form of stride). 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * need to do something reasonable (here creating a bigger texture). 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT); 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * This situation doesn't happen often, but some h/w have a limitation 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * for their framebuffer (eg: must be multiple of 8 pixels), and 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * we need to take that into account when using these buffers as 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * textures. 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * This should never be a problem with POT textures 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); 545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian unpack = 1 << ((unpack > 3) ? 3 : unpack); 546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); 547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * round to POT if needed 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 5513330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { 5523330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->NPOTAdjust = true; 5533330b203039dea366d4981db1408a460134b2d2cMathias Agopian } 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5553330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (texture->NPOTAdjust) { 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // find the smallest power-of-two that will accommodate our surface 5573330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->potWidth = 1 << (31 - clz(t.width)); 5583330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->potHeight = 1 << (31 - clz(t.height)); 5593330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (texture->potWidth < t.width) texture->potWidth <<= 1; 5603330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (texture->potHeight < t.height) texture->potHeight <<= 1; 5613330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->wScale = float(t.width) / texture->potWidth; 5623330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->hScale = float(t.height) / texture->potHeight; 5633330b203039dea366d4981db1408a460134b2d2cMathias Agopian } else { 5643330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->potWidth = t.width; 5653330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->potHeight = t.height; 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 5673330b203039dea366d4981db1408a460134b2d2cMathias Agopian 568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Rect bounds(dirty.bounds()); 569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GLvoid* data = 0; 5703330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (texture->width != t.width || texture->height != t.height) { 5713330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->width = t.width; 5723330b203039dea366d4981db1408a460134b2d2cMathias Agopian texture->height = t.height; 573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5743330b203039dea366d4981db1408a460134b2d2cMathias Agopian // texture size changed, we need to create a new one 5753330b203039dea366d4981db1408a460134b2d2cMathias Agopian bounds.set(Rect(t.width, t.height)); 5763330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (t.width == texture->potWidth && 5773330b203039dea366d4981db1408a460134b2d2cMathias Agopian t.height == texture->potHeight) { 5783330b203039dea366d4981db1408a460134b2d2cMathias Agopian // we can do it one pass 5793330b203039dea366d4981db1408a460134b2d2cMathias Agopian data = t.data; 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 5813330b203039dea366d4981db1408a460134b2d2cMathias Agopian 58254ed4f6282bdea251455f39b978626026affdbefMathias Agopian if (t.format == HAL_PIXEL_FORMAT_RGB_565) { 583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 5843330b203039dea366d4981db1408a460134b2d2cMathias Agopian GL_RGB, texture->potWidth, texture->potHeight, 0, 585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); 58654ed4f6282bdea251455f39b978626026affdbefMathias Agopian } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { 587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 5883330b203039dea366d4981db1408a460134b2d2cMathias Agopian GL_RGBA, texture->potWidth, texture->potHeight, 0, 589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); 59054ed4f6282bdea251455f39b978626026affdbefMathias Agopian } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || 59154ed4f6282bdea251455f39b978626026affdbefMathias Agopian t.format == HAL_PIXEL_FORMAT_RGBX_8888) { 592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 5933330b203039dea366d4981db1408a460134b2d2cMathias Agopian GL_RGBA, texture->potWidth, texture->potHeight, 0, 594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_BYTE, data); 59554ed4f6282bdea251455f39b978626026affdbefMathias Agopian } else if (isSupportedYuvFormat(t.format)) { 596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // just show the Y plane of YUV buffers 597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 5983330b203039dea366d4981db1408a460134b2d2cMathias Agopian GL_LUMINANCE, texture->potWidth, texture->potHeight, 0, 599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else { 601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // oops, we don't handle this format! 602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("layer %p, texture=%d, using format %d, which is not " 6033330b203039dea366d4981db1408a460134b2d2cMathias Agopian "supported by the GL", this, texture->name, t.format); 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 6063330b203039dea366d4981db1408a460134b2d2cMathias Agopian if (!data) { 60754ed4f6282bdea251455f39b978626026affdbefMathias Agopian if (t.format == HAL_PIXEL_FORMAT_RGB_565) { 608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 610076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride*2); 61254ed4f6282bdea251455f39b978626026affdbefMathias Agopian } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) { 613076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 614076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride*2); 61754ed4f6282bdea251455f39b978626026affdbefMathias Agopian } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 || 61854ed4f6282bdea251455f39b978626026affdbefMathias Agopian t.format == HAL_PIXEL_FORMAT_RGBX_8888) { 619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_BYTE, 622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride*4); 62354ed4f6282bdea251455f39b978626026affdbefMathias Agopian } else if (isSupportedYuvFormat(t.format)) { 624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // just show the Y plane of YUV buffers 625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_LUMINANCE, GL_UNSIGNED_BYTE, 628076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride); 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopianstatus_t LayerBase::initializeEglImage( 63454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian const sp<GraphicBuffer>& buffer, Texture* texture) 63554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian{ 63654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian status_t err = NO_ERROR; 63754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 63854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian // we need to recreate the texture 63954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 64054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 64154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian // free the previous image 64254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian if (texture->image != EGL_NO_IMAGE_KHR) { 64354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian eglDestroyImageKHR(dpy, texture->image); 64454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian texture->image = EGL_NO_IMAGE_KHR; 64554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } 64654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 64754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian // construct an EGL_NATIVE_BUFFER_ANDROID 64854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); 64954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 65054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian // create the new EGLImageKHR 65154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian const EGLint attrs[] = { 65254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 65354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian EGL_NONE, EGL_NONE 65454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian }; 65554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian texture->image = eglCreateImageKHR( 65654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, 65754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian (EGLClientBuffer)clientBuf, attrs); 65854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 65954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian if (texture->image != EGL_NO_IMAGE_KHR) { 66054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian glBindTexture(GL_TEXTURE_2D, texture->name); 66154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 66254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian (GLeglImageOES)texture->image); 66354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian GLint error = glGetError(); 66454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian if (UNLIKELY(error != GL_NO_ERROR)) { 66554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) " 66654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian "failed err=0x%04x", 66754ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian this, texture->image, error); 66854ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian err = INVALID_OPERATION; 66954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } else { 67054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian // Everything went okay! 67154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian texture->NPOTAdjust = false; 67254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian texture->dirty = false; 67354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian texture->width = clientBuf->width; 67454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian texture->height = clientBuf->height; 67554ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } 67654ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } else { 677fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x", 678fcfeb4b5970c8f361634429934a2518d7e8328ddMathias Agopian this, eglGetError()); 67954ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian err = INVALID_OPERATION; 68054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian } 68154ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian return err; 68254ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian} 68354ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 68454ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6872e123245811a1f31c080a29728fcc1655045f011Mathias Agopianint32_t LayerBaseClient::sIdentity = 0; 6882e123245811a1f31c080a29728fcc1655045f011Mathias Agopian 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 690f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, int32_t i) 691d12965934712ed0b9c1a264a6934dc0dad839ffdMathias Agopian : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i), 692948d69fca450a5a85e3e3e17d5776bfb26e48b85Mathias Agopian mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 69448d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian lcblk = new SharedBufferServer( 69548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian client->ctrlblk, i, NUM_BUFFERS, 69648d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mIdentity); 697076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 699076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::onFirstRef() 700076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 701f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian sp<Client> client(this->client.promote()); 702f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (client != 0) { 703076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian client->bindLayer(this, mIndex); 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBaseClient::~LayerBaseClient() 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 709f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian sp<Client> client(this->client.promote()); 710f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (client != 0) { 711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project client->free(mIndex); 712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 71348d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian delete lcblk; 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 716f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianint32_t LayerBaseClient::serverIndex() const 717f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian{ 718f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian sp<Client> client(this->client.promote()); 719f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (client != 0) { 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (client->cid<<16)|mIndex; 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0xFFFF0000 | mIndex; 723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 725076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> LayerBaseClient::getSurface() 726076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 727076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Surface> s; 728076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mLock); 729076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian s = mClientSurface.promote(); 730076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (s == 0) { 731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian s = createSurface(); 732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mClientSurface = s; 733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 734076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return s; 735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const 738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 7399a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return new Surface(mFlinger, clientIndex(), mIdentity, 740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<LayerBaseClient *>(this)); 741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 7430b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian// called with SurfaceFlinger::mStateLock as soon as the layer is entered 7440b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian// in the purgatory list 7450b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopianvoid LayerBaseClient::onRemoved() 7460b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian{ 7470b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian // wake up the condition 7480b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian lcblk->setStatus(NO_INIT); 7490b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian} 7500b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian 751076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 752076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 7539a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayerBaseClient::Surface::Surface( 7549a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian const sp<SurfaceFlinger>& flinger, 7559a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian SurfaceID id, int identity, 756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBaseClient>& owner) 7579a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner) 7589a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 760076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 7619a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayerBaseClient::Surface::~Surface() 7629a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 7639a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 7649a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * This is a good place to clean-up all client resources 7659a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 7669a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 7679a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian // destroy client resources 7689a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian sp<LayerBaseClient> layer = getOwner(); 7699a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian if (layer != 0) { 7709a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian mFlinger->destroySurface(layer); 7719a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 772076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 773076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 774076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const { 775076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> owner(mOwner.promote()); 776076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return owner; 777076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 778076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 779076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t LayerBaseClient::Surface::onTransact( 780375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 781076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 782076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian switch (code) { 783076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian case REGISTER_BUFFERS: 784076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian case UNREGISTER_BUFFERS: 785076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian case CREATE_OVERLAY: 786076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian { 787375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { 788375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 789375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 790375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 791375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 792375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 793375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 794076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 795076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 796076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 797076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return BnSurface::onTransact(code, data, reply, flags); 798076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 799076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 8003330b203039dea366d4981db1408a460134b2d2cMathias Agopiansp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 801076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 802076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NULL; 803076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 804076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 805076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t LayerBaseClient::Surface::registerBuffers( 806076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const ISurface::BufferHeap& buffers) 807076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 808076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return INVALID_OPERATION; 809076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 810076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 811076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::Surface::postBuffer(ssize_t offset) 812076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 813076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 814076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 815076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::Surface::unregisterBuffers() 816076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 817076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 818076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 819076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<OverlayRef> LayerBaseClient::Surface::createOverlay( 82052e7200b6e020bba978c36e3a928493a3f2c8a92Chih-Chung Chang uint32_t w, uint32_t h, int32_t format, int32_t orientation) 821076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 822076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NULL; 823076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}; 824edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 825edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 826edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 827edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 828