Surface.cpp revision 62185b7335e85211dc4d0e2003354eb3ea2e66ef
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 "Surface" 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h> 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IPCThreadState.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IMemory.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h> 33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/BufferMapper.h> 34076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/EGLNativeWindowSurface.h> 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurface.h> 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Surface.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/SurfaceComposerClient.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h> 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <EGL/android_natives.h> 41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/SharedState.h> 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/LayerState.h> 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <pixelflinger/pixelflinger.h> 46076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 50076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// SurfaceBuffer 51076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 52076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 534243e666213029a293935987c979831093fb0779Mathias Agopiantemplate<class SurfaceBuffer> Mutex Singleton<SurfaceBuffer>::sLock; 544243e666213029a293935987c979831093fb0779Mathias Agopiantemplate<> SurfaceBuffer* Singleton<SurfaceBuffer>::sInstance(0); 554243e666213029a293935987c979831093fb0779Mathias Agopian 56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::SurfaceBuffer() 57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian : BASE(), handle(0), mOwner(false) 58076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 59076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian width = 60076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian height = 61076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian stride = 62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian format = 63076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian usage = 0; 64076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t::getHandle = getHandle; 65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 66076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::SurfaceBuffer(const Parcel& data) 68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian : BASE(), handle(0), mOwner(true) 69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we own the handle in this case 71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian width = data.readInt32(); 72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian height = data.readInt32(); 73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian stride = data.readInt32(); 74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian format = data.readInt32(); 75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian usage = data.readInt32(); 76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian handle = data.readNativeHandle(); 77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t::getHandle = getHandle; 78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::~SurfaceBuffer() 81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (handle && mOwner) { 83076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian native_handle_close(handle); 84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian native_handle_delete(const_cast<native_handle*>(handle)); 85076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 86076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 87076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint SurfaceBuffer::getHandle(android_native_buffer_t const * base, 89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian buffer_handle_t* handle) 90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *handle = getSelf(base)->handle; 92076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 93076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 94076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 95076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceBuffer::writeToParcel(Parcel* reply, 96076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t const* buffer) 97076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian buffer_handle_t handle; 99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = buffer->getHandle(buffer, &handle); 100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err < 0) { 101076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 102076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 103076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->width); 104076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->height); 105076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->stride); 106076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->format); 107076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->usage); 108076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeNativeHandle(handle); 109076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 110076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 111076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 112076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------- 113076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 114076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatic void copyBlt(const android_native_buffer_t* dst, 115076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const android_native_buffer_t* src, const Region& reg) 116076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 117076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Region::iterator iterator(reg); 118076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (iterator) { 119076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // NOTE: dst and src must be the same format 120076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Rect r; 121076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t bpp = bytesPerPixel(src->format); 122076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t dbpr = dst->stride * bpp; 123076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t sbpr = src->stride * bpp; 124076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian while (iterator.iterate(&r)) { 125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian ssize_t h = r.bottom - r.top; 126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (h) { 127076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian size_t size = (r.right - r.left) * bpp; 128076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian uint8_t* s = (GGLubyte*)src->bits + 129076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian (r.left + src->stride * r.top) * bpp; 130076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian uint8_t* d = (GGLubyte*)dst->bits + 131076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian (r.left + dst->stride * r.top) * bpp; 132076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (dbpr==sbpr && size==sbpr) { 133076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian size *= h; 134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian h = 1; 135076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 136076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian do { 137076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian memcpy(d, s, size); 138076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian d += dbpr; 139076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian s += sbpr; 140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } while (--h > 0); 141076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 144076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 145076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 14662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 14762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 14862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// SurfaceControl 14962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 15062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 15162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 15262185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, 15362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<ISurface>& surface, 15462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const ISurfaceFlingerClient::surface_data_t& data, 15562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 15662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian bool owner) 15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian : mClient(client), mSurface(surface), 15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken(data.token), mIdentity(data.identity), 15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mFormat(format), mFlags(flags), mOwner(owner) 16062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl() 16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 16662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 16862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy() 16962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // Destroy the surface in SurfaceFlinger if we were the owner 17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // (in any case, a client won't be able to, because it won't have the 17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // right permission). 17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mOwner && mToken>=0 && mClient!=0) { 17462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient->destroySurface(mToken); 17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 17662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // clear all references and trigger an IPC now, to make sure things 17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // happen without delay, since these resources are quite heavy. 17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient.clear(); 18062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurface.clear(); 18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian IPCThreadState::self()->flushCommands(); 18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear() 18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 18662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // here, the window manager tells us explicitly that we should destroy 18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // the surface's resource. Soon after this call, it will also release 18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // its last reference (which will call the dtor); however, it is possible 18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // that a client living in the same process still holds references which 19062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // would delay the call to the dtor -- that is why we need this explicit 19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // "clear()" call. 19262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) { 19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 19762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 19862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setLayer(mToken, layer); 20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) { 20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 20462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setPosition(mToken, x, y); 20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) { 21062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setSize(mToken, w, h); 21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 21662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() { 21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 22062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->hide(mToken); 22262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) { 22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 22662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->show(mToken, layer); 22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() { 23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->freeze(mToken); 23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() { 23862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 23962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 24062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 24162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 24262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->unfreeze(mToken); 24362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 24462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { 24562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 24662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 24762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 24862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 24962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFlags(mToken, flags, mask); 25062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 25162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { 25262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 25362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 25462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 25562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 25662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setTransparentRegionHint(mToken, transparent); 25762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 25862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) { 25962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 26062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 26162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 26262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 26362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setAlpha(mToken, alpha); 26462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 26562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 26662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 26762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 26862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 26962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 27062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); 27162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 27262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) { 27362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 27462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (client == 0) return INVALID_OPERATION; 27562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 27662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 27762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFreezeTint(mToken, tint); 27862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 27962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 28062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopiansp<SurfaceControl> SurfaceControl::readFromParcel(Parcel* parcel) 28162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 28262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian sp<SurfaceComposerClient> client; 28362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian ISurfaceFlingerClient::surface_data_t data; 28462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian sp<IBinder> clientBinder= parcel->readStrongBinder(); 28562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian sp<ISurface> surface = interface_cast<ISurface>(parcel->readStrongBinder()); 28662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian data.token = parcel->readInt32(); 28762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian data.identity = parcel->readInt32(); 28862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian PixelFormat format = parcel->readInt32(); 28962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian uint32_t flags = parcel->readInt32(); 29062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 29162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (clientBinder != NULL) 29262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian client = SurfaceComposerClient::clientForConnection(clientBinder); 29362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 29462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return new SurfaceControl(client, surface, data, 0, 0, format, flags, false); 29562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 29662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 29762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::writeToParcel(const sp<SurfaceControl>& surface, Parcel* parcel) 29862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 29962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian uint32_t flags=0; 30062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian uint32_t format=0; 30162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian SurfaceID token = -1; 30262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian uint32_t identity = 0; 30362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian sp<SurfaceComposerClient> client; 30462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian sp<ISurface> sur; 30562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (SurfaceControl::isValid(surface)) { 30662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian token = surface->mToken; 30762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian identity = surface->mIdentity; 30862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian client = surface->mClient; 30962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian sur = surface->mSurface; 31062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian format = surface->mFormat; 31162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian flags = surface->mFlags; 31262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 31362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); 31462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 31562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian parcel->writeInt32(token); 31662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian parcel->writeInt32(identity); 31762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian parcel->writeInt32(format); 31862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian parcel->writeInt32(flags); 31962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_ERROR; 32062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 32162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 32262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianbool SurfaceControl::isSameSurface( 32362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 32462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 32562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (lhs == 0 || rhs == 0) 32662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return false; 32762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 32862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 32962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 33062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 33162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::validate(per_client_cblk_t const* cblk) const 33262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 33362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mToken<0 || mClient==0) { 33462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 33562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, mClient.get()); 33662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 33762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 33862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (cblk == 0) { 33962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); 34062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 34162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 34262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = cblk->validate(mToken); 34362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err != NO_ERROR) { 34462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", 34562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, err, strerror(-err)); 34662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return err; 34762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 34862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mIdentity != uint32_t(cblk->layers[mToken].identity)) { 34962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("using an invalid surface id=%d, identity=%u should be %d", 35062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, cblk->layers[mToken].identity); 35162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 35262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 35362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_ERROR; 35462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 35562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 356076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 357076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// Surface 358076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectSurface::Surface(const sp<SurfaceComposerClient>& client, 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const sp<ISurface>& surface, 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const ISurfaceFlingerClient::surface_data_t& data, 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool owner) 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mClient(client), mSurface(surface), 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mToken(data.token), mIdentity(data.identity), 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFormat(format), mFlags(flags), mOwner(owner) 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 36962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurfaceControl = new SurfaceControl( 37062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian client, surface, data, w, h, format, flags, owner); 37162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 372076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::connect = connect; 373076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::disconnect = disconnect; 374076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::setSwapInterval = setSwapInterval; 375076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::setSwapRectangle = setSwapRectangle; 376076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::dequeueBuffer = dequeueBuffer; 377076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::lockBuffer = lockBuffer; 378076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::queueBuffer = queueBuffer; 379076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle.makeInvalid(); 381076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 382076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian DisplayInfo dinfo; 383076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceComposerClient::getDisplayInfo(0, &dinfo); 384076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi; 385076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi; 386076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: set real values here 387076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::minSwapInterval) = 1; 388076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::maxSwapInterval) = 1; 389076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<uint32_t&>(android_native_window_t::flags) = 0; 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 39240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface() 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 39440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // this is a client-side operation, the surface is destroyed, unmap 39540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // its buffers in this process. 39640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian for (int i=0 ; i<2 ; i++) { 39740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (mBuffers[i] != 0) { 39840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian BufferMapper::get().unmap(mBuffers[i]->getHandle(), this); 39940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 40040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 40140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 40240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian destroy(); 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopianvoid Surface::destroy() 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 40762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurfaceControl->destroy(); 40840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 40940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // clear all references and trigger an IPC now, to make sure things 41040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // happen without delay, since these resources are quite heavy. 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mClient.clear(); 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurface.clear(); 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->flushCommands(); 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopianvoid Surface::clear() 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 41862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurfaceControl->clear(); 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::validate(per_client_cblk_t const* cblk) const 422076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 42340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (mToken<0 || mClient==0) { 42440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 42540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian mToken, mIdentity, mClient.get()); 42640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return NO_INIT; 42740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 428076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (cblk == 0) { 429076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); 430076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 431076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 432076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = cblk->validate(mToken); 433076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) { 434076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", 435076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mToken, mIdentity, err, strerror(-err)); 436076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 437076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 438076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mIdentity != uint32_t(cblk->layers[mToken].identity)) { 439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("using an invalid surface id=%d, identity=%u should be %d", 440076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mToken, mIdentity, cblk->layers[mToken].identity); 441076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 442076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 445076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 447076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 448076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::setSwapRectangle(android_native_window_t* window, 449076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int l, int t, int w, int h) 450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian self->setSwapRectangle(Rect(l, t, l+w, t+h)); 453076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 454076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::connect(android_native_window_t* window) 457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 459076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 460076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::disconnect(android_native_window_t* window) 461076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 462076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 463076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 464076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval) 465076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 466076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 467076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 468076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 469076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window, 470076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t** buffer) 471076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 472076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->dequeueBuffer(buffer); 474076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window, 477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t* buffer) 478076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 479076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 480076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->lockBuffer(buffer); 481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 482076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 483076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window, 484076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t* buffer) 485076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 486076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->queueBuffer(buffer); 488076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 489076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 491076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 492076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer) 493076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: dequeueBuffer() needs proper implementation 495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mSurfaceLock); 497076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 498076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 499076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = validate(cblk); 500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 501076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 503076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceID index(mToken); 504076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 505076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int32_t backIdx = cblk->lock_layer(size_t(index), 506076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t::BLOCKING); 507076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 508076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (backIdx < 0) 509076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return status_t(backIdx); 510076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 511076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mBackbufferIndex = backIdx; 512076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* const lcblk = &(cblk->layers[index]); 513076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 514076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian volatile const surface_info_t* const back = lcblk->surface + backIdx; 515076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (back->flags & surface_info_t::eNeedNewBuffer) { 516076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian getBufferLocked(backIdx); 517076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 518076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 519076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]); 520076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *buffer = backBuffer.get(); 521076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 522076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 523076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 524076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 525076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer) 526076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 52740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 52840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 52940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 53040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian status_t err = validate(cblk); 53140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (err != NO_ERROR) 53240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return err; 53340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 534076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: lockBuffer() needs proper implementation 535076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer) 539076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 540076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mSurfaceLock); 541076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 542076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = validate(cblk); 544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // transmit the dirty region 548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Region dirty(swapRectangle()); 549076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceID index(mToken); 550076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* const lcblk = &(cblk->layers[index]); 551076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian _send_dirty_region(lcblk, dirty); 552076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 553076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian uint32_t newstate = cblk->unlock_layer_and_post(size_t(index)); 554076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (!(newstate & eNextFlipPending)) 555076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mClient->signalServer(); 556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 557076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 560076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 561076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) { 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return Surface::lock(info, NULL, blocking); 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) 567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: needs some locking here 569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t* backBuffer; 570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = dequeueBuffer(&backBuffer); 571076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 572076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian err = lockBuffer(backBuffer); 573076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 574076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian backBuffer->common.incRef(&backBuffer->common); 575076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer = backBuffer; 576076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian other->w = backBuffer->width; 577076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian other->h = backBuffer->height; 578076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian other->s = backBuffer->stride; 579076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian other->usage = backBuffer->usage; 580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian other->format = backBuffer->format; 581076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian other->bits = backBuffer->bits; 582076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 583076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we handle copy-back here... 584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Rect bounds(backBuffer->width, backBuffer->height); 586076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Region newDirtyRegion; 587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 588076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]); 590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex; 591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (back->flags & surface_info_t::eBufferDirty) { 592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // content is meaningless in this case and the whole surface 593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // needs to be redrawn. 594076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian newDirtyRegion.set(bounds); 595076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (dirty) { 596076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *dirty = newDirtyRegion; 597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else 599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian { 600076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (dirty) { 601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian dirty->andSelf(Region(bounds)); 602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian newDirtyRegion = *dirty; 603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } else { 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian newDirtyRegion.set(bounds); 605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 606076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Region copyback; 607076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (!(lcblk->flags & eNoCopyBack)) { 608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Region previousDirtyRegion(dirtyRegion()); 609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian copyback = previousDirtyRegion.subtract(newDirtyRegion); 610076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]); 612076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (!copyback.isEmpty() && frontBuffer!=0) { 613076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // copy front to back 614076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian copyBlt(backBuffer, frontBuffer.get(), copyback); 615076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 616076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 617076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian setDirtyRegion(newDirtyRegion); 618076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Rect lockBounds(backBuffer->width, backBuffer->height); 621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (dirty) { 622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian lockBounds = dirty->bounds(); 623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 624076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian buffer_handle_t handle; 625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian backBuffer->getHandle(backBuffer, &handle); 626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t res = BufferMapper::get().lock(handle, 627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 628076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian lockBounds); 629076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGW_IF(res, "failed locking buffer %d (%p)", 630076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mBackbufferIndex, handle); 631076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian setSwapRectangle(lockBounds); 632076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 633076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 634076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 636076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost() 638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 639076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: needs some locking here 640076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 641076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mLockedBuffer == 0) 642076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return BAD_VALUE; 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 644076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian buffer_handle_t handle; 645076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer->getHandle(mLockedBuffer, &handle); 646076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t res = BufferMapper::get().unlock(handle); 647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGW_IF(res, "failed unlocking buffer %d (%p)", 648076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mBackbufferIndex, handle); 649076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 650076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Rect dirty(dirtyRegion().bounds()); 651076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian setSwapRectangle(dirty); 652076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = queueBuffer(mLockedBuffer); 653076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer->common.decRef(&mLockedBuffer->common); 654076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer = 0; 655076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 656edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 657edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 658076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::_send_dirty_region( 659076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* lcblk, const Region& dirty) 660076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 661076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift; 662076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian flat_region_t* flat_region = lcblk->region + index; 663076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = dirty.write(flat_region, sizeof(flat_region_t)); 664076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err < NO_ERROR) { 665076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // region doesn't fit, use the bounds 666076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Region reg(dirty.bounds()); 667076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reg.write(flat_region, sizeof(flat_region_t)); 668076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 669edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 670edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 671edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectRegion Surface::dirtyRegion() const { 672edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mDirtyRegion; 673edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 674edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setDirtyRegion(const Region& region) const { 675edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mDirtyRegion = region; 676edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 677edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst Rect& Surface::swapRectangle() const { 678edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSwapRectangle; 679edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 680edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) { 681edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle = r; 682edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 683edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 684edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<Surface> Surface::readFromParcel(Parcel* parcel) 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 686edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<SurfaceComposerClient> client; 687edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ISurfaceFlingerClient::surface_data_t data; 688edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> clientBinder= parcel->readStrongBinder(); 689edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<ISurface> surface = interface_cast<ISurface>(parcel->readStrongBinder()); 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.token = parcel->readInt32(); 691edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.identity = parcel->readInt32(); 692edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project PixelFormat format = parcel->readInt32(); 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = parcel->readInt32(); 694edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 695edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (clientBinder != NULL) 696edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project client = SurfaceComposerClient::clientForConnection(clientBinder); 697edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return new Surface(client, surface, data, 0, 0, format, flags, false); 699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 700edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel) 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 703edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags=0; 704edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t format=0; 705edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SurfaceID token = -1; 706edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t identity = 0; 707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<SurfaceComposerClient> client; 708edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<ISurface> sur; 70940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (Surface::isValid(surface)) { 710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project token = surface->mToken; 711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project identity = surface->mIdentity; 712edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project client = surface->mClient; 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sur = surface->mSurface; 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project format = surface->mFormat; 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project flags = surface->mFlags; 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel->writeInt32(token); 720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel->writeInt32(identity); 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel->writeInt32(format); 722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel->writeInt32(flags); 723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 725edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs) 727edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 728edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (lhs == 0 || rhs == 0) 729edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 730edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 731edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 732edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::getBufferLocked(int index) 734edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 735076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = NO_MEMORY; 736076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<SurfaceBuffer> buffer = mSurface->getBuffer(); 737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL"); 738076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (buffer != 0) { 739076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<SurfaceBuffer>& currentBuffer(mBuffers[index]); 740076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (currentBuffer != 0) { 7414243e666213029a293935987c979831093fb0779Mathias Agopian BufferMapper::get().unmap(currentBuffer->getHandle(), this); 742076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian currentBuffer.clear(); 743076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 7444243e666213029a293935987c979831093fb0779Mathias Agopian err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits, this); 745076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); 746076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 747076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian currentBuffer = buffer; 748edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 750076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 751edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 75362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 75462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 75562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setLayer(int32_t layer) { 75662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setLayer(layer); 75762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 75862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setPosition(int32_t x, int32_t y) { 75962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setPosition(x, y); 76062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 76162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setSize(uint32_t w, uint32_t h) { 76262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setSize(w, h); 76362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 76462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::hide() { 76562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->hide(); 76662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 76762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::show(int32_t layer) { 76862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->show(layer); 76962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 77062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::freeze() { 77162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->freeze(); 77262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 77362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::unfreeze() { 77462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->unfreeze(); 77562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 77662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setFlags(uint32_t flags, uint32_t mask) { 77762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setFlags(flags, mask); 77862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 77962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setTransparentRegionHint(const Region& transparent) { 78062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setTransparentRegionHint(transparent); 78162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 78262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setAlpha(float alpha) { 78362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setAlpha(alpha); 78462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 78562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 78662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setMatrix(dsdx, dtdx, dsdy, dtdy); 78762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 78862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t Surface::setFreezeTint(uint32_t tint) { 78962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return mSurfaceControl->setFreezeTint(tint); 79062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 79162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 79262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 793edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 794edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 795