Layer.cpp revision edbf3b6af777b721cd2a1ef461947e51e88241e1
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#define LOG_TAG "SurfaceFlinger" 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/StopWatch.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/PixelFormat.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/EGLDisplaySurface.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "clz.h" 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "Layer.h" 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "LayerBitmap.h" 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "SurfaceFlinger.h" 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "VRamHeap.h" 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h" 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define DEBUG_RESIZE 0 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4; 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* const Layer::typeID = "Layer"; 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i) 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : LayerBaseClient(flinger, display, c, i), 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecure(false), 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrontBufferIndex(1), 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mNeedsBlending(true), 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mResizeTransactionDone(false), 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTextureName(-1U), mTextureWidth(0), mTextureHeight(0) 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // no OpenGL operation is possible here, since we might not be 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in the OpenGL thread. 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectLayer::~Layer() 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project client->free(clientIndex()); 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this should always be called from the OpenGL thread 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mTextureName != -1U) { 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //glDeleteTextures(1, &mTextureName); 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project deletedTextures.add(mTextureName); 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::initStates(uint32_t w, uint32_t h, uint32_t flags) 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LayerBase::initStates(w,h,flags); 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & ISurfaceComposer::eDestroyBackbuffer) 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project lcblk->flags |= eNoCopyBack; 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<LayerBaseClient::Surface> Layer::getSurface() const 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSurface; 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Layer::setBuffers( Client* client, 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t w, uint32_t h, 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format, uint32_t flags) 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormatInfo info; 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = getPixelFormatInfo(format, &info); 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err) return err; 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: if eHardware is explicitly requested, we should fail 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // on systems where we can't allocate memory that can be used with 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // DMA engines for instance. 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // FIXME: we always ask for hardware for now (this should come from copybit) 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= ISurfaceComposer::eHardware; 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t memory_flags = flags & 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (ISurfaceComposer::eGPU | 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ISurfaceComposer::eHardware | 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ISurfaceComposer::eSecure); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // pixel-alignment. the final alignment may be bigger because 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we always force a 4-byte aligned bpr. 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t alignment = 1; 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & ISurfaceComposer::eGPU) { 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // FIXME: this value should come from the h/w 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project alignment = 8; 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // FIXME: this is msm7201A specific, as its GPU only supports 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // BGRA_8888. 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (format == PIXEL_FORMAT_RGBA_8888) { 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = PIXEL_FORMAT_BGRA_8888; 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<MemoryDealer> allocators[2]; 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<2 ; i++) { 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project allocators[i] = client->createAllocator(memory_flags); 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (allocators[i] == 0) 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_MEMORY; 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBuffers[i].init(allocators[i]); 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS); 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err != NO_ERROR) 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBuffers[i].clear(); // clear the bits for security 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBuffers[i].getInfo(lcblk->surface + i); 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurface = new Surface(clientIndex(), 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project allocators[0]->getMemoryHeap(), 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project allocators[1]->getMemoryHeap(), 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mIdentity); 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::reloadTexture(const Region& dirty) 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mTextureName == -1U)) { 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // create the texture name the first time 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // can't do that in the ctor, because it runs in another thread. 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mTextureName = createTexture(); 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GGLSurface& t(frontBuffer().surface()); 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight); 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::onDraw(const Region& clip) const 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(mTextureName == -1LU)) { 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGW("Layer %p doesn't have a texture", this); 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the texture has not been created yet, this Layer has 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in fact never been drawn into. this happens frequently with 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // SurfaceView. 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project clearWithOpenGL(clip); 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const DisplayHardware& hw(graphicPlane(0).displayHardware()); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerBitmap& front(frontBuffer()); 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const GGLSurface& t(front.surface()); 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = NO_ERROR; 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int can_use_copybit = canUseCopybit(); 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (can_use_copybit) { 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // StopWatch watch("copybit"); 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const State& s(drawingState()); 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit_image_t dst; 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project hw.getDisplaySurface(&dst); 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const copybit_rect_t& drect 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds); 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit_image_t src; 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project front.getBitmapSurface(&src); 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit_rect_t srect = { 0, 0, t.width, t.height }; 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit_device_t* copybit = mFlinger->getBlitEngine(); 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation()); 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project copybit->set_parameter(copybit, COPYBIT_DITHER, 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project s.flags & ISurfaceComposer::eLayerDither ? 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project COPYBIT_ENABLE : COPYBIT_DISABLE); 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project region_iterator it(clip); 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!can_use_copybit || err) { 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project drawWithOpenGL(clip, mTextureName, t); 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h) 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "reallocateBuffer (layer=%p), " 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "requested (%dx%d), " 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "index=%d, (%dx%d), (%dx%d)", 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this, 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(w), int(h), 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(index), 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[0].width()), int(mBuffers[0].height()), 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[1].width()), int(mBuffers[1].height())); 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = mBuffers[index].resize(w, h); 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == NO_ERROR) { 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBuffers[index].getInfo(lcblk->surface + index); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s", 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project index, w, h, err, strerror(err)); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // XXX: what to do, what to do? We could try to free some 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // hidden surfaces, instead of killing this one? 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t Layer::doTransaction(uint32_t flags) 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& front(drawingState()); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& temp(currentState()); 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the test front.{w|h} != temp.{w|h} is not enough because it is possible 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // that the size changed back to its previous value before the buffer 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // was resized (in the eLocked case below), in which case, we still 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // need to execute the code below so the clients have a chance to be 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // release. resze() deals with the fact that the size can be the same. 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Various states we could be in... 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project resize = state & eResizeRequested; 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (backbufferChanged) { 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (resize == 0) { 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // ERROR, the resized buffer doesn't have its resize flag set 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (resize == mask) { 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // ERROR one of the buffer has already been resized 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (resize == mask ^ eResizeRequested) { 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // ERROR, the resized buffer doesn't have its resize flag set 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (resize == eResizeRequested) { 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // OK, Normal case, proceed with resize 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (resize == 0) { 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // OK, nothing special, do nothing 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (resize == mask) { 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // restarted transaction, do nothing 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (resize == mask ^ eResizeRequested) { 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // restarted transaction, do nothing 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (resize == eResizeRequested) { 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // OK, size reset to previous value, proceed with resize 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Index of the back buffer 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h); 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t state = lcblk->swapState; 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t clientBackBufferIndex = layer_cblk_t::backBuffer(state); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0; 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t resizeFlags = state & eResizeRequested; 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(backbufferChanged && (resizeFlags != eResizeRequested))) { 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE( "backbuffer size changed, but both resize flags are not set! " 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "(layer=%p), state=%08x, requested (%dx%d), drawing (%d,%d), " 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "index=%d, (%dx%d), (%dx%d)", 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this, state, 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(temp.w), int(temp.h), 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(drawingState().w), int(drawingState().h), 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(clientBackBufferIndex), 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[0].width()), int(mBuffers[0].height()), 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[1].width()), int(mBuffers[1].height())); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if we get there we're pretty screwed. the only reasonable 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // thing to do is to pretend we should do the resize since 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // backbufferChanged is set (this also will give a chance to 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // client to get unblocked) 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project resizeFlags = eResizeRequested; 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (resizeFlags == eResizeRequested) { 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // NOTE: asserting that clientBackBufferIndex!=mFrontBufferIndex 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // here, would be wrong and misleading because by this point 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // mFrontBufferIndex has not been updated yet. 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "resize (layer=%p), state=%08x, " 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "requested (%dx%d), " 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "drawing (%d,%d), " 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "index=%d, (%dx%d), (%dx%d)", 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this, state, 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(temp.w), int(temp.h), 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(drawingState().w), int(drawingState().h), 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(clientBackBufferIndex), 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[0].width()), int(mBuffers[0].height()), 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[1].width()), int(mBuffers[1].height())); 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (state & eLocked) { 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if the buffer is locked, we can't resize anything because 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // - the backbuffer is currently in use by the user 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // - the front buffer is being shown 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // We just act as if the transaction didn't happen and we 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // reschedule it later... 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags |= eRestartTransaction; 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // This buffer needs to be resized 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project resize(clientBackBufferIndex, temp.w, temp.h, "transaction"); 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err == NO_ERROR) { 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0; 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_and(~mask, &(lcblk->swapState)); 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // since a buffer became available, we can let the client go... 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->scheduleBroadcast(client); 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mResizeTransactionDone = true; 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // we're being resized and there is a freeze display request, 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // acquire a freeze lock, so that the screen stays put 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // until we've redrawn at the new size; this is to avoid 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // glitches upon orientation changes. 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mFlinger->hasFreezeRequest()) { 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if the surface is hidden, don't try to acquire the 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // freeze lock, since hidden surfaces may never redraw 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock = mFlinger->getFreezeLock(); 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.sequence != front.sequence) { 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this surface is now hidden, so it shouldn't hold a freeze lock 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // (it may never redraw, which is fine if it is hidden) 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return LayerBase::doTransaction(flags); 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Layer::resize( 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t clientBackBufferIndex, 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t width, uint32_t height, 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* what) 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project /* 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * handle resize (backbuffer and frontbuffer reallocation) 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]); 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if the new (transaction) size is != from the the backbuffer 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // then we need to reallocate the backbuffer 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool backbufferChanged = (clientBackBuffer.width() != width) || 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (clientBackBuffer.height() != height); 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(!backbufferChanged, 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "(%s) eResizeRequested (layer=%p), but size not changed: " 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "requested (%dx%d), drawing (%d,%d), current (%d,%d)," 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "state=%08lx, index=%d, (%dx%d), (%dx%d)", 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project what, this, 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(width), int(height), 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(drawingState().w), int(drawingState().h), 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(currentState().w), int(currentState().h), 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project long(lcblk->swapState), 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(clientBackBufferIndex), 375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[0].width()), int(mBuffers[0].height()), 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[1].width()), int(mBuffers[1].height())); 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // this can happen when changing the size back and forth quickly 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = NO_ERROR; 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (backbufferChanged) { 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project err = reallocateBuffer(clientBackBufferIndex, width, height); 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(err != NO_ERROR)) { 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // couldn't reallocate the surface 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write(eInvalidSurface, &lcblk->swapState); 386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t)); 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err; 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::setSizeChanged(uint32_t w, uint32_t h) 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "setSizeChanged w=%d, h=%d (old: w=%d, h=%d)", 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project w, h, mCurrentState.w, mCurrentState.h); 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_or(eResizeRequested, &(lcblk->swapState)); 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// pageflip handling... 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::lockPageFlip(bool& recomputeVisibleRegions) 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t state = android_atomic_or(eBusy, &(lcblk->swapState)); 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // preemptively block the client, because he might set 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // eFlipRequested at any time and want to use this buffer 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // for the next frame. This will be unset below if it 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // turns out we didn't need it. 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t mask = eInvalidSurface | eFlipRequested | eResizeRequested; 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!(state & mask)) 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(state & eInvalidSurface)) { 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if eInvalidSurface is set, this means the surface 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // became invalid during a transaction (NO_MEMORY for instance) 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->scheduleBroadcast(client); 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(state & eFlipRequested)) { 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t oldState; 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion = post(&oldState, recomputeVisibleRegions); 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (oldState & eNextFlipPending) { 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Process another round (we know at least a buffer 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is ready for that client). 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->signalEvent(); 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions) 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // atomically swap buffers and (re)set eFlipRequested 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t oldValue, newValue; 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project layer_cblk_t * const lcblk = this->lcblk; 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project do { 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project oldValue = lcblk->swapState; 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // get the current value 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOG_ASSERT(oldValue&eFlipRequested, 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "eFlipRequested not set, yet we're flipping! (state=0x%08lx)", 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project long(oldValue)); 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project newValue = (oldValue ^ eIndex); 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // swap buffers 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project newValue &= ~(eFlipRequested | eNextFlipPending); 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // clear eFlipRequested and eNextFlipPending 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (oldValue & eNextFlipPending) 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project newValue |= eFlipRequested; 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // if eNextFlipPending is set (second buffer already has something 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in it) we need to reset eFlipRequested because the client 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // might never do it 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState))); 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *previousSate = oldValue; 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const int32_t index = (newValue & eIndex) ^ 1; 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFrontBufferIndex = index; 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // ... post the new front-buffer 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirty(lcblk->region + index); 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirty.andSelf(frontBuffer().bounds()); 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n", 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // oldValue, newValue, mFrontBufferIndex); 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //dirty.dump("dirty"); 471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (UNLIKELY(oldValue & eResizeRequested)) { 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(DEBUG_RESIZE, 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "post (layer=%p), state=%08x, " 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "index=%d, (%dx%d), (%dx%d)", 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this, newValue, 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(1-index), 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[0].width()), int(mBuffers[0].height()), 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int(mBuffers[1].width()), int(mBuffers[1].height())); 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // here, we just posted the surface and we have resolved 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the front/back buffer indices. The client is blocked, so 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // it cannot start using the new backbuffer. 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // If the backbuffer was resized in THIS round, we actually cannot 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // resize the frontbuffer because it has *just* been drawn (and we 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // would have nothing to draw). In this case we just skip the resize 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // it'll happen after the next page flip or during the next 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transaction. 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const uint32_t mask = (1-index) ? eResizeBuffer1 : eResizeBuffer0; 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mResizeTransactionDone && (newValue & mask)) { 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Resize the layer's second buffer only if the transaction 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // happened. It may not have happened yet if eResizeRequested 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // was set immediately after the "transactionRequested" test, 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // in which case the drawing state's size would be wrong. 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFreezeLock.clear(); 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (resize(1-index, s.w, s.h, "post") == NO_ERROR) { 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project do { 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project oldValue = lcblk->swapState; 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if ((oldValue & eResizeRequested) == eResizeRequested) { 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // ugh, another resize was requested since we processed 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the first buffer, don't free the client, and let 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // the next transaction handle everything. 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project newValue = oldValue & ~mask; 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState))); 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mResizeTransactionDone = false; 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project recomputeVisibleRegions = true; 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project this->contentDirty = true; 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reloadTexture(dirty); 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return dirty; 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectPoint Layer::getPhysicalSize() const 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const LayerBitmap& front(frontBuffer()); 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return Point(front.width(), front.height()); 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::unlockPageFlip( 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform& planeTransform, Region& outDirtyRegion) 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Region dirtyRegion(mPostedDirtyRegion); 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!dirtyRegion.isEmpty()) { 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mPostedDirtyRegion.clear(); 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // The dirty region is given in the layer's coordinate space 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // transform the dirty region by the surface's transformation 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // and the global transformation. 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Layer::State& s(drawingState()); 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const Transform tr(planeTransform * s.transform); 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion = tr.transform(dirtyRegion); 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // At this point, the dirty region is in screen space. 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Make sure it's constrained by the visible region (which 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // is in screen space as well). 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project dirtyRegion.andSelf(visibleRegionScreen); 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project outDirtyRegion.orSelf(dirtyRegion); 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // client could be blocked, so signal them so they get a 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // chance to reevaluate their condition. 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->scheduleBroadcast(client); 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Layer::finishPageFlip() 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (LIKELY(!(lcblk->swapState & eInvalidSurface))) { 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(!(lcblk->swapState & eBusy), 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "layer %p wasn't locked!", this); 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_and(~eBusy, &(lcblk->swapState)); 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlinger->scheduleBroadcast(client); 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 569