LayerBase.cpp revision 7e4a587f6038bcf9b58ca615fce9e52fd47e30c3
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), 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransactionFlags(0), 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPremultipliedAlpha(true), 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mInvalidate(0) 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlags = hw.getFlags(); 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBase::~LayerBase() 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst GraphicPlane& LayerBase::graphicPlane(int dpy) const 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlinger->graphicPlane(dpy); 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGraphicPlane& LayerBase::graphicPlane(int dpy) 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlinger->graphicPlane(dpy); 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t layerFlags = 0; 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & ISurfaceComposer::eHidden) 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layerFlags = ISurfaceComposer::eLayerHidden; 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & ISurfaceComposer::eNonPremultiplied) 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPremultipliedAlpha = false; 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 867e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.z = 0; 877e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.w = w; 887e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.h = h; 897e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_w = w; 907e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_h = h; 917e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.alpha = 0xFF; 927e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.flags = layerFlags; 937e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.sequence = 0; 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set(0, 0); 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // drawing state & current state are identical 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 100ba6be54876a19444f0b214b4b3b0749df227b013Mathias Agopianvoid LayerBase::commitTransaction() { 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDrawingState = mCurrentState; 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::forceVisibilityTransaction() { 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this can be called without SurfaceFlinger.mStateLock, but if we 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // can atomically increment the sequence number, it doesn't matter. 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&mCurrentState.sequence); 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::requestTransaction() { 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t old = setTransactionFlags(eTransactionNeeded); 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return ((old & eTransactionNeeded) == 0); 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::getTransactionFlags(uint32_t flags) { 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_and(~flags, &mTransactionFlags) & flags; 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::setTransactionFlags(uint32_t flags) { 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return android_atomic_or(flags, &mTransactionFlags); 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setPosition(int32_t x, int32_t y) { 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set(x, y); 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setLayer(uint32_t z) { 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.z == z) 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.z = z; 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setSize(uint32_t w, uint32_t h) { 1377e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if (mCurrentState.requested_w == w && mCurrentState.requested_h == h) 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 1397e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_w = w; 1407e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian mCurrentState.requested_h = h; 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setAlpha(uint8_t alpha) { 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.alpha == alpha) 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.alpha = alpha; 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: check the matrix has changed 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transform.set( 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setTransparentRegionHint(const Region& transparent) { 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: check the region has changed 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.transparentRegion = transparent; 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool LayerBase::setFlags(uint8_t flags, uint8_t mask) { 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mCurrentState.flags == newFlags) 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.sequence++; 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mCurrentState.flags = newFlags; 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project requestTransaction(); 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return true; 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRect LayerBase::visibleBounds() const 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mTransformedBounds; 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::setVisibleRegion(const Region& visibleRegion) { 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // always called from main thread 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project visibleRegionScreen = visibleRegion; 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::setCoveredRegion(const Region& coveredRegion) { 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // always called from main thread 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project coveredRegionScreen = coveredRegion; 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t LayerBase::doTransaction(uint32_t flags) 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1977e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian if ((front.requested_w != temp.requested_w) || 1987e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian (front.requested_h != temp.requested_h)) { 1997e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian // resize the layer, set the physical size to the requested size 2007e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian Layer::State& editTemp(currentState()); 2017e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian editTemp.w = temp.requested_w; 2027e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian editTemp.h = temp.requested_h; 2037e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian } 2047e4a587f6038bcf9b58ca615fce9e52fd47e30c3Mathias Agopian 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // invalidate and recompute the visible regions if needed 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eVisibleRegion; 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this->contentDirty = true; 209a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian 210a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian const bool linearFiltering = mUseLinearFiltering; 211a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian mUseLinearFiltering = false; 212a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 213a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian // we may use linear filtering, if the matrix scales us 214a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian const uint8_t type = temp.transform.getType(); 215a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) { 216a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian mUseLinearFiltering = true; 217a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 218a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 219a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 220a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Commit the transaction 222ba6be54876a19444f0b214b4b3b0749df227b013Mathias Agopian commitTransaction(); 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return flags; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::validateVisibility(const Transform& planeTransform) 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool transformed = tr.transformed(); 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 232cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian uint32_t w = s.w; 233cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian uint32_t h = s.h; 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[0], 0, 0); 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[1], 0, h); 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[2], w, h); 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project tr.transform(mVertices[3], w, 0); 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(transformed)) { 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // NOTE: here we could also punt if we have too many rectangles 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in the transparent region 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (tr.preserveRects()) { 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the transparent region 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project transparentRegionScreen = tr.transform(s.transparentRegion); 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transformation too complex, can't do the transparent region 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // optimization. 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project transparentRegionScreen.clear(); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project transparentRegionScreen = s.transparentRegion; 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // cache a few things... 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mOrientation = tr.getOrientation(); 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransformedBounds = tr.makeBounds(w, h); 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTransformed = transformed; 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mLeft = tr.tx(); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTop = tr.ty(); 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::lockPageFlip(bool& recomputeVisibleRegions) 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::unlockPageFlip( 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(visibleRegionScreen); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::finishPageFlip() 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::invalidate() 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((android_atomic_or(1, &mInvalidate)&1) == 0) { 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->signalEvent(); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::drawRegion(const Region& reg) const 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 28620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = reg.begin(); 28720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = reg.end(); 28820f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian if (it != end) { 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Rect r; 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t fbWidth = hw.getWidth(); 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t fbHeight = hw.getHeight(); 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { fbWidth, fbHeight }, { 0, fbHeight } }; 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glVertexPointer(2, GL_SHORT, 0, vertices); 29620f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian while (it != end) { 29720f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian const Rect& r = *it++; 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GLint sy = fbHeight - (r.top + r.height()); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glScissor(r.left, sy, r.width(), r.height()); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::draw(const Region& inClip) const 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // invalidate the region we'll update 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region clip(inClip); // copy-on-write, so no-op most of the time 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Remove the transparent area from the clipping region 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const State& s = drawingState(); 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!s.transparentRegion.isEmpty())) { 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project clip.subtract(transparentRegionScreen); 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (clip.isEmpty()) { 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // usually this won't happen because this should be taken care of 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // by SurfaceFlinger::computeVisibleRegions() 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // reset GL state 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_SCISSOR_TEST); 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project onDraw(clip); 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_TEXTURE_2D); 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_BLEND); 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glColor4x(0, 0x8000, 0, 0x10000); 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project drawRegion(transparentRegionScreen); 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectGLuint LayerBase::createTexture() const 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLuint textureName = -1; 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glGenTextures(1, &textureName); 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, textureName); 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 344a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 345a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return textureName; 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34929aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavinvoid LayerBase::clearWithOpenGL(const Region& clip, GLclampx red, 35029aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin GLclampx green, GLclampx blue, 35129aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin GLclampx alpha) const 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t fbHeight = hw.getHeight(); 35529aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin glColor4x(red,green,blue,alpha); 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_TEXTURE_2D); 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_DITHER); 35920f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian 36020f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator it = clip.begin(); 36120f68782a4ea71c6a977d7f87d8288d3daa265ecMathias Agopian Region::const_iterator const end = clip.end(); 36295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glEnable(GL_SCISSOR_TEST); 36395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glVertexPointer(2, GL_FIXED, 0, mVertices); 36495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian while (it != end) { 36595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const Rect& r = *it++; 36695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const GLint sy = fbHeight - (r.top + r.height()); 36795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 36895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 37229aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavinvoid LayerBase::clearWithOpenGL(const Region& clip) const 37329aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin{ 37429aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin clearWithOpenGL(clip,0,0,0,0); 37529aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin} 37629aa74c546751ed04d17dc248a967eebaef63b21Rebecca Schultz Zavin 3771fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopianvoid LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t fbHeight = hw.getHeight(); 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const State& s(drawingState()); 3820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // bind our texture 3841fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian validateTexture(texture.name); 3851fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian uint32_t width = texture.width; 3861fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian uint32_t height = texture.height; 3871fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_TEXTURE_2D); 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(s.alpha < 0xFF)) { 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // We have an alpha-modulation. We need to modulate all 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // texture components by alpha because we're always using 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // premultiplied alpha. 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the texture doesn't have an alpha channel we can 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // use REPLACE and switch to non premultiplied alpha 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // blending (SRCA/ONE_MINUS_SRCA). 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLenum env, src; 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (needsBlending()) { 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project env = GL_MODULATE; 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project env = GL_REPLACE; 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project src = GL_SRC_ALPHA; 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GGLfixed alpha = (s.alpha << 16)/255; 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glColor4x(alpha, alpha, alpha, alpha); 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_BLEND); 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glColor4x(0x10000, 0x10000, 0x10000, 0x10000); 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (needsBlending()) { 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glEnable(GL_BLEND); 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glDisable(GL_BLEND); 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian Region::const_iterator it = clip.begin(); 42595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian Region::const_iterator const end = clip.end(); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(transformed() 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //StopWatch watch("GL transformed"); 43095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const GLfixed texCoords[4][2] = { 43195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian { 0, 0 }, 43295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian { 0, 0x10000 }, 43395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian { 0x10000, 0x10000 }, 43495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian { 0x10000, 0 } 43595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian }; 43695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian 43795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glMatrixMode(GL_TEXTURE); 43895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glLoadIdentity(); 43995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian 44095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // the texture's source is rotated 44195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (texture.transform == HAL_TRANSFORM_ROT_90) { 44295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // TODO: handle the other orientations 44395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glTranslatef(0, 1, 0); 44495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glRotatef(-90, 0, 0, 1); 44595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian } 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 44795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (!(mFlags & (DisplayHardware::NPOT_EXTENSION | 44895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian DisplayHardware::DIRECT_TEXTURE))) { 44995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian // find the smallest power-of-two that will accommodate our surface 45095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian GLuint tw = 1 << (31 - clz(width)); 45195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian GLuint th = 1 << (31 - clz(height)); 45295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (tw < width) tw <<= 1; 45395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian if (th < height) th <<= 1; 45495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian GLfloat ws = GLfloat(width) /tw; 45595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian GLfloat hs = GLfloat(height)/th; 45695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glScalef(ws, hs, 1.0f); 45795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian } 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glEnableClientState(GL_TEXTURE_COORD_ARRAY); 46095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glVertexPointer(2, GL_FIXED, 0, mVertices); 46195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glTexCoordPointer(2, GL_FIXED, 0, texCoords); 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian while (it != end) { 46495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const Rect& r = *it++; 46595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const GLint sy = fbHeight - (r.top + r.height()); 46695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 46795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 46995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glDisableClientState(GL_TEXTURE_COORD_ARRAY); 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 47195a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian GLint crop[4] = { 0, height, width, -height }; 47295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); 47395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian int x = tx(); 47495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian int y = ty(); 47595a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian y = fbHeight - (y + height); 47695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian while (it != end) { 47795a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const Rect& r = *it++; 47895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian const GLint sy = fbHeight - (r.top + r.height()); 47995a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glScissor(r.left, sy, r.width(), r.height()); 48095a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian glDrawTexiOES(x, y, 0, width, height); 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid LayerBase::validateTexture(GLint textureName) const 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, textureName); 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: reload the texture if needed 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this is currently done in loadTexture() below 490a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian if (mUseLinearFiltering) { 491a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 492a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 493a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } else { 494a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 495a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 496a2fe0a234bd6823f868742a3c137acb8875e1b03Mathias Agopian } 497401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian 498401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian if (needsDithering()) { 499401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian glEnable(GL_DITHER); 500401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian } else { 501401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian glDisable(GL_DITHER); 502401c257fba770a267f637184b1f532b4e03bed20Mathias Agopian } 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5051fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopianvoid LayerBase::loadTexture(Texture* texture, GLint textureName, 5061fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian const Region& dirty, const GGLSurface& t) const 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: defer the actual texture reload until LayerBase::validateTexture 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is called. 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5111fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian texture->name = textureName; 5121fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian GLuint& textureWidth(texture->width); 5131fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian GLuint& textureHeight(texture->height); 5141fed11c86a9d59d0f5282ae8ae25ceba2f802fddMathias Agopian 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = mFlags; 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project glBindTexture(GL_TEXTURE_2D, textureName); 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLuint tw = t.width; 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLuint th = t.height; 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * In OpenGL ES we can't specify a stride with glTexImage2D (however, 523076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian * GL_UNPACK_ALIGNMENT is a limited form of stride). 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * need to do something reasonable (here creating a bigger texture). 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT); 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * This situation doesn't happen often, but some h/w have a limitation 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * for their framebuffer (eg: must be multiple of 8 pixels), and 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * we need to take that into account when using these buffers as 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * textures. 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * This should never be a problem with POT textures 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 536076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 537076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format)); 538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian unpack = 1 << ((unpack > 3) ? 3 : unpack); 539076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); 540076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * round to POT if needed 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLuint texture_w = tw; 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GLuint texture_h = th; 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!(flags & DisplayHardware::NPOT_EXTENSION)) { 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // find the smallest power-of-two that will accommodate our surface 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project texture_w = 1 << (31 - clz(t.width)); 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project texture_h = 1 << (31 - clz(t.height)); 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (texture_w < t.width) texture_w <<= 1; 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (texture_h < t.height) texture_h <<= 1; 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 554076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectregular: 556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Rect bounds(dirty.bounds()); 557076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GLvoid* data = 0; 558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (texture_w!=textureWidth || texture_h!=textureHeight) { 559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // texture size changed, we need to create a new one 560076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 561076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (!textureWidth || !textureHeight) { 562076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // this is the first time, load the whole texture 563076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (texture_w==tw && texture_h==th) { 564076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we can do it one pass 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data = t.data; 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we have to create the texture first because it 568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // doesn't match the size of the buffer 569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian bounds.set(Rect(tw, th)); 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 572076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (t.format == GGL_PIXEL_FORMAT_RGB_565) { 574076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 575076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGB, texture_w, texture_h, 0, 576076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); 577076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { 578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, texture_w, texture_h, 0, 580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); 581816d7d0268f98d891c44a8ac2e52711958abbf05Mathias Agopian } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888 || 582816d7d0268f98d891c44a8ac2e52711958abbf05Mathias Agopian t.format == GGL_PIXEL_FORMAT_RGBX_8888) { 583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, texture_w, texture_h, 0, 585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_BYTE, data); 586076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || 587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { 588076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // just show the Y plane of YUV buffers 589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexImage2D(GL_TEXTURE_2D, 0, 590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_LUMINANCE, texture_w, texture_h, 0, 591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_LUMINANCE, GL_UNSIGNED_BYTE, data); 592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else { 593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // oops, we don't handle this format! 594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("layer %p, texture=%d, using format %d, which is not " 595076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian "supported by the GL", this, textureName, t.format); 596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian textureName = -1; 597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian textureWidth = texture_w; 599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian textureHeight = texture_h; 600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (!data && textureName>=0) { 602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (t.format == GGL_PIXEL_FORMAT_RGB_565) { 603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 606076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride*2); 607076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { 608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 610076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride*2); 612816d7d0268f98d891c44a8ac2e52711958abbf05Mathias Agopian } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888 || 613816d7d0268f98d891c44a8ac2e52711958abbf05Mathias Agopian t.format == GGL_PIXEL_FORMAT_RGBX_8888) { 614076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_RGBA, GL_UNSIGNED_BYTE, 617076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride*4); 618076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || 619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { 620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // just show the Y plane of YUV buffers 621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian glTexSubImage2D(GL_TEXTURE_2D, 0, 622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 0, bounds.top, t.width, bounds.height(), 623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GL_LUMINANCE, GL_UNSIGNED_BYTE, 624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian t.data + bounds.top*t.stride); 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6312e123245811a1f31c080a29728fcc1655045f011Mathias Agopianint32_t LayerBaseClient::sIdentity = 0; 6322e123245811a1f31c080a29728fcc1655045f011Mathias Agopian 633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 634f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian const sp<Client>& client, int32_t i) 63548d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian : LayerBase(flinger, display), lcblk(NULL), client(client), 636cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 637edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 63848d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian lcblk = new SharedBufferServer( 63948d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian client->ctrlblk, i, NUM_BUFFERS, 64048d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian mIdentity); 641076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 642edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 643076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::onFirstRef() 644076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 645f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian sp<Client> client(this->client.promote()); 646f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (client != 0) { 647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian client->bindLayer(this, mIndex); 648edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 649edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 650edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 651edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayerBaseClient::~LayerBaseClient() 652edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 653f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian sp<Client> client(this->client.promote()); 654f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (client != 0) { 655edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project client->free(mIndex); 656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 65748d819a1315f7d1b5abfec9d4fd34fb5aed27b1dMathias Agopian delete lcblk; 658edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 659edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 660f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopianint32_t LayerBaseClient::serverIndex() const 661f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian{ 662f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian sp<Client> client(this->client.promote()); 663f9d932774e06d5122c48b47d8cabd791783f56d2Mathias Agopian if (client != 0) { 664edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return (client->cid<<16)|mIndex; 665edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 666edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0xFFFF0000 | mIndex; 667edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 668edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 669076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> LayerBaseClient::getSurface() 670076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 671076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<Surface> s; 672076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mLock); 673076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian s = mClientSurface.promote(); 674076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (s == 0) { 675076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian s = createSurface(); 676076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mClientSurface = s; 677076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 678076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return s; 679076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 680076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 681076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const 682076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 6839a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian return new Surface(mFlinger, clientIndex(), mIdentity, 684076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<LayerBaseClient *>(this)); 685076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 686076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 687076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// --------------------------------------------------------------------------- 688076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 6899a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayerBaseClient::Surface::Surface( 6909a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian const sp<SurfaceFlinger>& flinger, 6919a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian SurfaceID id, int identity, 692076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<LayerBaseClient>& owner) 6939a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner) 6949a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 695076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 696076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 697076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 6989a11206fe793363c0e8897b478cbe6ef8c52b543Mathias AgopianLayerBaseClient::Surface::~Surface() 6999a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian{ 7009a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian /* 7019a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian * This is a good place to clean-up all client resources 7029a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian */ 7039a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian 7049a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian // destroy client resources 7059a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian sp<LayerBaseClient> layer = getOwner(); 7069a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian if (layer != 0) { 7079a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian mFlinger->destroySurface(layer); 7089a11206fe793363c0e8897b478cbe6ef8c52b543Mathias Agopian } 709076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 710076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 711076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const { 712076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<LayerBaseClient> owner(mOwner.promote()); 713076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return owner; 714076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 715076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 716076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t LayerBaseClient::Surface::onTransact( 717375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 718076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 719076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian switch (code) { 720076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian case REGISTER_BUFFERS: 721076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian case UNREGISTER_BUFFERS: 722076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian case CREATE_OVERLAY: 723076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian { 724375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) { 725375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian IPCThreadState* ipc = IPCThreadState::self(); 726375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int pid = ipc->getCallingPid(); 727375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian const int uid = ipc->getCallingUid(); 728375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian LOGE("Permission Denial: " 729375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 730375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian return PERMISSION_DENIED; 731076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 734076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return BnSurface::onTransact(code, data, reply, flags); 735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 737cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopiansp<SurfaceBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 739076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NULL; 740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 741076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t LayerBaseClient::Surface::registerBuffers( 743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const ISurface::BufferHeap& buffers) 744076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 745076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return INVALID_OPERATION; 746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 747076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 748076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::Surface::postBuffer(ssize_t offset) 749076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 750076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 751076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 752076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid LayerBaseClient::Surface::unregisterBuffers() 753076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 754076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 755076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 756076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopiansp<OverlayRef> LayerBaseClient::Surface::createOverlay( 757076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian uint32_t w, uint32_t h, int32_t format) 758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 759076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NULL; 760076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}; 761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 763edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 764edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 765