Surface.cpp revision 579b3f88d03d06b897b778bd11818f5104677d1d
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 <errno.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h> 26cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <utils/CallStack.h> 279cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <utils/Log.h> 289cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 29c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h> 333330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferMapper.h> 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h> 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 379cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/Surface.h> 389cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurface.h> 399cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurfaceComposer.h> 409cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/SurfaceComposerClient.h> 41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 429cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/SharedBufferStack.h> 439cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/LayerState.h> 44076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------- 48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 4914998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt( 503330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& dst, 513330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& src, 520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const Region& reg) 53076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 54245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // src and dst with, height and format must be identical. no verification 55245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // is done here. 5614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian status_t err; 5714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t const * src_bits = NULL; 5814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); 5914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking src buffer %s", strerror(-err)); 600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t* dst_bits = NULL; 6214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); 6314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); 6414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 6514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator head(reg.begin()); 6614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator tail(reg.end()); 6714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (head != tail && src_bits && dst_bits) { 68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t bpp = bytesPerPixel(src->format); 69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t dbpr = dst->stride * bpp; 70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t sbpr = src->stride * bpp; 710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 7214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian while (head != tail) { 7314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian const Rect& r(*head++); 740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian ssize_t h = r.height(); 750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (h <= 0) continue; 760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian size_t size = r.width() * bpp; 770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; 780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; 790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (dbpr==sbpr && size==sbpr) { 800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian size *= h; 810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian h = 1; 82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian do { 840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian memcpy(d, s, size); 850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian d += dbpr; 860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian s += sbpr; 870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } while (--h > 0); 88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 9114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (src_bits) 9214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian src->unlock(); 9314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 9414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (dst_bits) 9514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian dst->unlock(); 9614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 9714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian return err; 98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 10062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 10162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// SurfaceControl 10262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 10362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 10401b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurfaceControl::SurfaceControl( 10501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceComposerClient>& client, 10662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<ISurface>& surface, 1077e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian const ISurfaceComposerClient::surface_data_t& data, 10818d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) 10962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian : mClient(client), mSurface(surface), 11062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken(data.token), mIdentity(data.identity), 1111c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian mWidth(data.width), mHeight(data.height), mFormat(data.format), 1121c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian mFlags(flags) 11362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 11462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 11518d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian 11662185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl() 11762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 11862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 11962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 12062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 12162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy() 12262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 12318d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian if (isValid()) { 12462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient->destroySurface(mToken); 12562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 12662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 12762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // clear all references and trigger an IPC now, to make sure things 12862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // happen without delay, since these resources are quite heavy. 12962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient.clear(); 13062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurface.clear(); 13162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian IPCThreadState::self()->flushCommands(); 13262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 13362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 13462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear() 13562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 13662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // here, the window manager tells us explicitly that we should destroy 13762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // the surface's resource. Soon after this call, it will also release 13862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // its last reference (which will call the dtor); however, it is possible 13962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // that a client living in the same process still holds references which 14062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // would delay the call to the dtor -- that is why we need this explicit 14162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // "clear()" call. 14262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 14362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 14462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 14501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool SurfaceControl::isSameSurface( 14601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 14701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 14801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (lhs == 0 || rhs == 0) 14901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return false; 15001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 15101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 15201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 15362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) { 154963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 15562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 156631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setLayer(mToken, layer); 15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) { 160963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 162631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setPosition(mToken, x, y); 16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) { 166963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 168631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 16962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setSize(mToken, w, h); 17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() { 172963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 174631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->hide(mToken); 17662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) { 178963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 180631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->show(mToken, layer); 18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() { 184963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 186631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->freeze(mToken); 18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() { 190963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 192631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->unfreeze(mToken); 19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { 196963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 19762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 198631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFlags(mToken, flags, mask); 20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { 202963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 204631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setTransparentRegionHint(mToken, transparent); 20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) { 208963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 210631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setAlpha(mToken, alpha); 21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 214963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 216631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); 21862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) { 220963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 222631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFreezeTint(mToken, tint); 22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 226963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t SurfaceControl::validate() const 22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mToken<0 || mClient==0) { 22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, mClient.get()); 23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_ERROR; 23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 23601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel( 23701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& control, Parcel* parcel) 23801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 239579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<ISurface> sur; 24001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t identity = 0; 241cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t width = 0; 242cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t height = 0; 243579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t format = 0; 244579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t flags = 0; 24501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (SurfaceControl::isValid(control)) { 24601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sur = control->mSurface; 247579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian identity = control->mIdentity; 248cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian width = control->mWidth; 249cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian height = control->mHeight; 25001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian format = control->mFormat; 25101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian flags = control->mFlags; 25201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 253b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 25401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(identity); 255cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(width); 256cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(height); 25701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(format); 25801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(flags); 25901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return NO_ERROR; 26001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 26101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 26201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const 26301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 26401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian Mutex::Autolock _l(mLock); 26501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (mSurfaceData == 0) { 26601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mSurfaceData = new Surface(const_cast<SurfaceControl*>(this)); 26701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return mSurfaceData; 26901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 27001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 271076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 272076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// Surface 273076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 275b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianclass SurfaceClient : public Singleton<SurfaceClient> 276b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian{ 277b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // all these attributes are constants 278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<ISurfaceComposer> mComposerService; 279b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<ISurfaceComposerClient> mClient; 280b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian status_t mStatus; 281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedClient* mControl; 282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<IMemoryHeap> mControlMemory; 283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 284b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SurfaceClient() 285b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : Singleton<SurfaceClient>(), mStatus(NO_INIT) 286b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian { 287b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian sp<ISurfaceComposer> sf(ComposerService::getComposerService()); 288b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mComposerService = sf; 289b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mClient = sf->createClientConnection(); 290b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (mClient != NULL) { 291b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mControlMemory = mClient->getControlBlock(); 292b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (mControlMemory != NULL) { 293b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mControl = static_cast<SharedClient *>( 294b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mControlMemory->getBase()); 295b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (mControl) { 296b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mStatus = NO_ERROR; 297b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 298b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 299b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 300b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 301b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian friend class Singleton<SurfaceClient>; 302b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopianpublic: 303b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian status_t initCheck() const { 304b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mStatus; 305b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 306b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian SharedClient* getSharedClient() const { 307b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mControl; 308b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 309b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian ssize_t getTokenForSurface(const sp<ISurface>& sur) const { 310b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: we could cache a few tokens here to avoid an IPC 311b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian return mClient->getTokenForSurface(sur); 312b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 313b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian void signalServer() const { 314b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mComposerService->signal(); 315b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 316b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}; 317b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 318b7e930db175c192464cebdeb49eb56cf6dd60114Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient); 319b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 320b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 321b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 32201b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface) 323b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mBufferMapper(GraphicBufferMapper::get()), 324b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mClient(SurfaceClient::getInstance()), 325b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSharedBufferClient(NULL), 326631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian mInitCheck(NO_INIT), 327b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSurface(surface->mSurface), 328b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mIdentity(surface->mIdentity), 329b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mFormat(surface->mFormat), mFlags(surface->mFlags), 330ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian mWidth(surface->mWidth), mHeight(surface->mHeight) 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 33201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 33301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 33462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 335a0c30e924193da57723fd53b710ce6be24fb26f5Mathias AgopianSurface::Surface(const Parcel& parcel, const sp<IBinder>& ref) 336b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian : mBufferMapper(GraphicBufferMapper::get()), 337b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mClient(SurfaceClient::getInstance()), 338b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSharedBufferClient(NULL), 339b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mInitCheck(NO_INIT) 34001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 341a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian mSurface = interface_cast<ISurface>(ref); 34201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mIdentity = parcel.readInt32(); 343cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth = parcel.readInt32(); 344cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mHeight = parcel.readInt32(); 34501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFormat = parcel.readInt32(); 34601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFlags = parcel.readInt32(); 34701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 34801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 34901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 350579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopianstatus_t Surface::writeToParcel( 351579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const sp<Surface>& surface, Parcel* parcel) 352579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{ 353579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<ISurface> sur; 354579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t identity = 0; 355579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t width = 0; 356579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t height = 0; 357579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t format = 0; 358579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t flags = 0; 359579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (Surface::isValid(surface)) { 360579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sur = surface->mSurface; 361579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian identity = surface->mIdentity; 362579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian width = surface->mWidth; 363579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian height = surface->mHeight; 364579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian format = surface->mFormat; 365579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian flags = surface->mFlags; 366579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 367579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 368579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(identity); 369579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(width); 370579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(height); 371579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(format); 372579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(flags); 373579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return NO_ERROR; 374579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 375579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 376579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 377a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopiansp<Surface> Surface::readFromParcel( 378a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian const Parcel& data, const sp<Surface>& other) 379a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian{ 380a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian sp<Surface> result(other); 381a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian sp<IBinder> binder(data.readStrongBinder()); 382a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian if (other==0 || binder != other->mSurface->asBinder()) { 383a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian result = new Surface(data, binder); 384a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian } 385a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian return result; 386a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian} 387a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian 38801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init() 38901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 390076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::setSwapInterval = setSwapInterval; 391076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::dequeueBuffer = dequeueBuffer; 392076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::lockBuffer = lockBuffer; 393076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::queueBuffer = queueBuffer; 394cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian android_native_window_t::query = query; 3955221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian android_native_window_t::perform = perform; 396631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 397076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian DisplayInfo dinfo; 398076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceComposerClient::getDisplayInfo(0, &dinfo); 399076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi; 400076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi; 401076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: set real values here 402076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::minSwapInterval) = 1; 403076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::maxSwapInterval) = 1; 404076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<uint32_t&>(android_native_window_t::flags) = 0; 405631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 40655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian mConnected = 0; 407631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian mSwapRectangle.makeInvalid(); 408a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // two buffers by default 409a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBuffers.setCapacity(2); 410a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBuffers.insertAt(0, 2); 411631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 412b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian if (mSurface != 0 && mClient.initCheck() == NO_ERROR) { 413579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian int32_t token = mClient.getTokenForSurface(mSurface); 414579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (token >= 0) { 415b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSharedBufferClient = new SharedBufferClient( 416579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mClient.getSharedClient(), token, 2, mIdentity); 417579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mInitCheck = mClient.getSharedClient()->validate(token); 418b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 419631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian } 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface() 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 42440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // this is a client-side operation, the surface is destroyed, unmap 42540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // its buffers in this process. 426a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian size_t size = mBuffers.size(); 427a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian for (size_t i=0 ; i<size ; i++) { 42850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) { 42921c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian getBufferMapper().unregisterBuffer(mBuffers[i]->handle); 43040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 43140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 43240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 43340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // clear all references and trigger an IPC now, to make sure things 43440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // happen without delay, since these resources are quite heavy. 435a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBuffers.clear(); 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurface.clear(); 437cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian delete mSharedBufferClient; 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->flushCommands(); 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 441ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianbool Surface::isValid() { 442631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian return mInitCheck == NO_ERROR; 443ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 444ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 445963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t Surface::validate() const 446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 447631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // check that we initialized ourself properly 448631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian if (mInitCheck != NO_ERROR) { 449579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGE("invalid token (identity=%u)", mIdentity); 450631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian return mInitCheck; 45140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 452631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 453631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // verify the identity of this surface 4547e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian uint32_t identity = mSharedBufferClient->getIdentity(); 455631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 456631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // this is a bit of a (temporary) special case, identity==0 means that 457631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // no operation are allowed from the client (eg: dequeue/queue), this 458631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // is used with PUSH_BUFFER surfaces for instance 459631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian if (identity == 0) { 460631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian LOGE("[Surface] invalid operation (identity=%u)", mIdentity); 461631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian return INVALID_OPERATION; 462631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian } 463631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 464631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian if (mIdentity != identity) { 465579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGE("[Surface] using an invalid surface, " 466631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian "identity=%u should be %d", 467579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mIdentity, identity); 468076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 469076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 470631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 471631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // check the surface didn't become invalid 4727e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian status_t err = mSharedBufferClient->getStatus(); 473076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) { 474579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGE("surface (identity=%u) is invalid, err=%d (%s)", 475579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian mIdentity, err, strerror(-err)); 476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 478631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 479076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 480076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 482631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopiansp<ISurface> Surface::getISurface() const { 483631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian return mSurface; 484631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian} 485631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 486076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 488cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval) { 489076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 491076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 492076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window, 493cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian android_native_buffer_t** buffer) { 494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->dequeueBuffer(buffer); 496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 497076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 498076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window, 499cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian android_native_buffer_t* buffer) { 500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 501076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->lockBuffer(buffer); 502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 503076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 504076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window, 505cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian android_native_buffer_t* buffer) { 506076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 507076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->queueBuffer(buffer); 508076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 509076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 510cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(android_native_window_t* window, 511cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int what, int* value) { 512cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian Surface* self = getSelf(window); 513cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return self->query(what, value); 514cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 515cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 5165221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(android_native_window_t* window, 517cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int operation, ...) { 5185221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_list args; 5195221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_start(args, operation); 5205221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian Surface* self = getSelf(window); 5215221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian int res = self->perform(operation, args); 5225221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_end(args); 5235221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian return res; 5245221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian} 5255221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian 526076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 527076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 528a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::needNewBuffer(int bufIdx, 529a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t *pWidth, uint32_t *pHeight, 530a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t *pFormat, uint32_t *pUsage) const 531a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{ 532a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 533a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 534a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // Always call needNewBuffer(), since it clears the needed buffers flags 535a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx); 536a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]); 537a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian bool newNeewBuffer = needNewBuffer || !validBuffer; 538a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (newNeewBuffer) { 539a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferInfo.get(pWidth, pHeight, pFormat, pUsage); 540a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 541a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return newNeewBuffer; 542a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 543a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer) 545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 546963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 549076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 550cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t bufIdx = mSharedBufferClient->dequeue(); 551cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (bufIdx < 0) { 552cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE("error dequeuing a buffer (%s)", strerror(bufIdx)); 553cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return bufIdx; 55404bc12bd4316e2928134037cd0f81c6d8b2adcc8Mathias Agopian } 55568a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian 556a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // grow the buffer array if needed 557a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const size_t size = mBuffers.size(); 558a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const size_t needed = bufIdx+1; 559a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (size < needed) { 560a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBuffers.insertAt(size, needed-size); 561a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 5623a8069566724c87d1a88843e6430439e5d2a2e33Mathias Agopian 563a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, h, format, usage; 564a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) { 565a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian err = getBufferLocked(bufIdx, w, h, format, usage); 566a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)", 567a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian bufIdx, w, h, format, usage, strerror(-err)); 56850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (err == NO_ERROR) { 56950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian // reset the width/height with the what we get from the buffer 570a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]); 57150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian mWidth = uint32_t(backBuffer->width); 57250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian mHeight = uint32_t(backBuffer->height); 57350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian } 574076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 575076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 576cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // if we still don't have a buffer here, we probably ran out of memory 577a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]); 578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (!err && backBuffer==0) { 579cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = NO_MEMORY; 580cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 581cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 582cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian if (err == NO_ERROR) { 583cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mDirtyRegion.set(backBuffer->width, backBuffer->height); 584cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *buffer = backBuffer.get(); 585cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 586cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mSharedBufferClient->undoDequeue(bufIdx); 587cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian } 58850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian 589cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian return err; 590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer) 593076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 594963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 59540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (err != NO_ERROR) 59640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return err; 59740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 598b296533607232357597b255679db29470ab5925dMathias Agopian int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer)); 599cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = mSharedBufferClient->lock(bufIdx); 600cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err)); 601cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return err; 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer) 605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 606963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 607076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 609076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 6100926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (mSwapRectangle.isValid()) { 6110926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mDirtyRegion.set(mSwapRectangle); 6120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 6130926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 614b296533607232357597b255679db29470ab5925dMathias Agopian int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer)); 615cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop); 616cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); 617cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = mSharedBufferClient->queue(bufIdx); 618cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err)); 619076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 620cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR) { 621b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian // TODO: can we avoid this IPC if we know there is one pending? 622b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mClient.signalServer(); 623cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 624cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return err; 625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 627cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value) 628cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{ 629cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian switch (what) { 630cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case NATIVE_WINDOW_WIDTH: 631cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *value = int(mWidth); 632cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case NATIVE_WINDOW_HEIGHT: 634cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *value = int(mHeight); 635cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 636cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case NATIVE_WINDOW_FORMAT: 637cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *value = int(mFormat); 638cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 639cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian } 640cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return BAD_VALUE; 641cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 642cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 6435221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(int operation, va_list args) 6445221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{ 645cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian status_t err = validate(); 646cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian if (err != NO_ERROR) 647cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian return err; 648cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian 6495221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian int res = NO_ERROR; 6505221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian switch (operation) { 65155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_SET_USAGE: 65255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian dispatch_setUsage( args ); 65355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 65455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_CONNECT: 65555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian res = dispatch_connect( args ); 65655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 65755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_DISCONNECT: 65855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian res = dispatch_disconnect( args ); 65955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 660cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian case NATIVE_WINDOW_SET_CROP: 661cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian res = dispatch_crop( args ); 662cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian break; 663f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian case NATIVE_WINDOW_SET_BUFFER_COUNT: 664f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian res = dispatch_set_buffer_count( args ); 665f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian break; 66638ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: 66738ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian res = dispatch_set_buffers_geometry( args ); 66838ece279eac69541536073f8502d8d8af51ce4a9Mathias Agopian break; 66955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian default: 67055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian res = NAME_NOT_FOUND; 67155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 6725221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian } 6735221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian return res; 6745221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian} 6755221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian 67655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianvoid Surface::dispatch_setUsage(va_list args) { 67755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian int usage = va_arg(args, int); 67855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian setUsage( usage ); 67955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian} 68055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_connect(va_list args) { 68155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian int api = va_arg(args, int); 68255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian return connect( api ); 68355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian} 68455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::dispatch_disconnect(va_list args) { 68555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian int api = va_arg(args, int); 68655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian return disconnect( api ); 68755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian} 688cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::dispatch_crop(va_list args) { 689cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); 690cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian return crop( reinterpret_cast<Rect const*>(rect) ); 691cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian} 692f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopianint Surface::dispatch_set_buffer_count(va_list args) { 693f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian size_t bufferCount = va_arg(args, size_t); 694f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian return setBufferCount(bufferCount); 695f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian} 696a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::dispatch_set_buffers_geometry(va_list args) { 697a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int w = va_arg(args, int); 698a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int h = va_arg(args, int); 699a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian int f = va_arg(args, int); 700a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return setBuffersGeometry(w, h, f); 701a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 70255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 703ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianvoid Surface::setUsage(uint32_t reqUsage) 704ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian{ 705ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 706a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferInfo.set(reqUsage); 707ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 708ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 70955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::connect(int api) 71055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{ 71155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 71255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian int err = NO_ERROR; 71355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian switch (api) { 71455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_API_EGL: 71555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian if (mConnected) { 71655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian err = -EINVAL; 71755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } else { 71855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian mConnected = api; 71955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } 72055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 72155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian default: 72255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian err = -EINVAL; 72355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 72455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } 72555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian return err; 72655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian} 72755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 72855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopianint Surface::disconnect(int api) 72955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian{ 73055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 73155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian int err = NO_ERROR; 73255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian switch (api) { 73355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian case NATIVE_WINDOW_API_EGL: 73455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian if (mConnected == api) { 73555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian mConnected = 0; 73655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } else { 73755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian err = -EINVAL; 73855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } 73955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 74055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian default: 74155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian err = -EINVAL; 74255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian break; 74355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } 74455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian return err; 74555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian} 74655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 747cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopianint Surface::crop(Rect const* rect) 748cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian{ 749cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian Mutex::Autolock _l(mSurfaceLock); 750cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian // TODO: validate rect size 751cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian mNextBufferCrop = *rect; 752cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian return NO_ERROR; 753cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian} 754cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian 755b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopianint Surface::setBufferCount(int bufferCount) 756b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian{ 757b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian sp<ISurface> s(mSurface); 758b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian if (s == 0) return NO_INIT; 759b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 760bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback { 761bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian sp<ISurface> surface; 762bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian virtual status_t operator()(int bufferCount) const { 763bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian return surface->setBufferCount(bufferCount); 764bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } 765bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian public: 766bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { } 767bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian } ipc(s); 768b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 769bb641244d7d73312dc65b8e338df18b22e335107Mathias Agopian status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc); 770b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s", 771b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian bufferCount, strerror(-err)); 772b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian return err; 773b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian} 774b5b7f260da2c1a2a82e0311e2015d49a82f43667Mathias Agopian 775a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::setBuffersGeometry(int w, int h, int format) 776a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{ 777a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (w<0 || h<0 || format<0) 778a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return BAD_VALUE; 779a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 780a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((w && !h) || (!w && h)) 781a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return BAD_VALUE; 782a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 783a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 784a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mBufferInfo.set(w, h, format); 785a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return NO_ERROR; 786a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 787a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 788a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ---------------------------------------------------------------------------- 789a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 790a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianint Surface::getConnectedApi() const 791a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{ 792a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 793a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return mConnected; 794a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 79555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 796076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 797076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 798edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) { 799edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return Surface::lock(info, NULL, blocking); 800edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 801edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 8020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 803076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 80455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian if (getConnectedApi()) { 80555fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian LOGE("Surface::lock(%p) failed. Already connected to another API", 80655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian (android_native_window_t*)this); 80755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian CallStack stack; 80855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian stack.update(); 80955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian stack.dump(""); 81055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian return INVALID_OPERATION; 81155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } 81255fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 813cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mApiLock.tryLock() != NO_ERROR) { 8149014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian LOGE("calling Surface::lock from different threads!"); 815cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian CallStack stack; 816cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian stack.update(); 81755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian stack.dump(""); 818cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return WOULD_BLOCK; 819cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 8209014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian 8219014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian /* Here we're holding mApiLock */ 822cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 8239014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian if (mLockedBuffer != 0) { 8249014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian LOGE("Surface::lock failed, already locked"); 8259014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian mApiLock.unlock(); 8269014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian return INVALID_OPERATION; 8279014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian } 8289014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian 8295221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian // we're intending to do software rendering from this point 830ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 831ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 832b296533607232357597b255679db29470ab5925dMathias Agopian android_native_buffer_t* out; 833b296533607232357597b255679db29470ab5925dMathias Agopian status_t err = dequeueBuffer(&out); 834cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); 835076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 836b296533607232357597b255679db29470ab5925dMathias Agopian sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); 837cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = lockBuffer(backBuffer.get()); 838cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)", 839b296533607232357597b255679db29470ab5925dMathias Agopian getBufferIndex(backBuffer), strerror(-err)); 840076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 841076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Rect bounds(backBuffer->width, backBuffer->height); 842245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian const Region boundsRegion(bounds); 843245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian Region scratch(boundsRegion); 8440926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); 845245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian newDirtyRegion &= boundsRegion; 846076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 847245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // figure out if we can copy the frontbuffer back 8483330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); 849245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian const bool canCopyBack = (frontBuffer != 0 && 850245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian backBuffer->width == frontBuffer->width && 851245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian backBuffer->height == frontBuffer->height && 852245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian backBuffer->format == frontBuffer->format && 853245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian !(mFlags & ISurfaceComposer::eDestroyBackbuffer)); 854245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian 855245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // the dirty region we report to surfaceflinger is the one 856245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // given by the user (as opposed to the one *we* return to the 857245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // user). 858245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian mDirtyRegion = newDirtyRegion; 859245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian 860245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian if (canCopyBack) { 861245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // copy the area that is invalid and not repainted this round 862245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); 863245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian if (!copyback.isEmpty()) 864cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian copyBlt(backBuffer, frontBuffer, copyback); 865245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian } else { 866245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // if we can't copy-back anything, modify the user's dirty 867245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // region to make sure they redraw the whole buffer 868245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian newDirtyRegion = boundsRegion; 869076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 870cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 871245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // keep track of the are of the buffer that is "clean" 872245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // (ie: that will be redrawn) 8730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mOldDirtyRegion = newDirtyRegion; 874076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 875e71212ba5397387100a578d23b15862518a7a859Mathias Agopian void* vaddr; 8760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t res = backBuffer->lock( 8770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 878e71212ba5397387100a578d23b15862518a7a859Mathias Agopian newDirtyRegion.bounds(), &vaddr); 8790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 880cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGW_IF(res, "failed locking buffer (handle = %p)", 881cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian backBuffer->handle); 8820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 8830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mLockedBuffer = backBuffer; 8840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->w = backBuffer->width; 8850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->h = backBuffer->height; 8860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->s = backBuffer->stride; 8870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->usage = backBuffer->usage; 8880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->format = backBuffer->format; 889e71212ba5397387100a578d23b15862518a7a859Mathias Agopian other->bits = vaddr; 890076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 891076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 892cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mApiLock.unlock(); 893076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 894edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 895076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 896076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost() 897076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 898cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mLockedBuffer == 0) { 8999014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian LOGE("Surface::unlockAndPost failed, no locked buffer"); 9009014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian return INVALID_OPERATION; 901cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 902edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 903cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = mLockedBuffer->unlock(); 904cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); 9050926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 906cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = queueBuffer(mLockedBuffer.get()); 907cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)", 908b296533607232357597b255679db29470ab5925dMathias Agopian getBufferIndex(mLockedBuffer), strerror(-err)); 909cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 910cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mPostedBuffer = mLockedBuffer; 911076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer = 0; 912076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 913edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 914edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 915edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) { 916ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 917edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle = r; 918edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 919edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 920b296533607232357597b255679db29470ab5925dMathias Agopianint Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const 921b296533607232357597b255679db29470ab5925dMathias Agopian{ 922b296533607232357597b255679db29470ab5925dMathias Agopian return buffer->getIndex(); 923b296533607232357597b255679db29470ab5925dMathias Agopian} 924b296533607232357597b255679db29470ab5925dMathias Agopian 925a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianstatus_t Surface::getBufferLocked(int index, 926a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 927edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 928ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian sp<ISurface> s(mSurface); 929ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian if (s == 0) return NO_INIT; 930ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 931076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = NO_MEMORY; 93250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian 93350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian // free the current buffer 934a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index)); 93550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (currentBuffer != 0) { 93650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian getBufferMapper().unregisterBuffer(currentBuffer->handle); 93750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian currentBuffer.clear(); 93850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian } 93950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian 940a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage); 941cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(buffer==0, 942cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "ISurface::getBuffer(%d, %08x) returned NULL", 943cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian index, usage); 94450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (buffer != 0) { // this should never happen by construction 945cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(buffer->handle == NULL, 946a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) " 947a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian "returned a buffer with a null handle", 948a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mIdentity, index, w, h, format, usage); 9490b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian err = mSharedBufferClient->getStatus(); 9500b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian LOGE_IF(err, "Surface (identity=%d) state = %d", mIdentity, err); 9510b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian if (!err && buffer->handle != NULL) { 95250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian err = getBufferMapper().registerBuffer(buffer->handle); 95350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian LOGW_IF(err, "registerBuffer(...) failed %d (%s)", 95450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian err, strerror(-err)); 95550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (err == NO_ERROR) { 95650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian currentBuffer = buffer; 957cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian currentBuffer->setIndex(index); 95850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian } 959d3144beec6acb37702629799a2adbeccc72ca222Mathias Agopian } else { 960f10d7fde03218c17251416a34d7b726a43ec528aMathias Agopian err = err<0 ? err : status_t(NO_MEMORY); 961edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 962edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 963076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 964edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 965edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 966a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ---------------------------------------------------------------------------- 967a138f89c5e78b7e8994823e97d6e860869762837Mathias AgopianSurface::BufferInfo::BufferInfo() 968a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian : mWidth(0), mHeight(0), mFormat(0), 969a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0) 970a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian{ 971a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 972a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 973a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) { 974a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if ((mWidth != w) || (mHeight != h) || (mFormat != format)) { 975a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mWidth = w; 976a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mHeight = h; 977a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mFormat = format; 978a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mDirty |= GEOMETRY; 979a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 980a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 981a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 982a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::set(uint32_t usage) { 983a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mUsage = usage; 984a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 985a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 986a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianvoid Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight, 987a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian uint32_t *pFormat, uint32_t *pUsage) const { 988a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian *pWidth = mWidth; 989a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian *pHeight = mHeight; 990a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian *pFormat = mFormat; 991a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian *pUsage = mUsage; 992a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 993a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 994a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopianbool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const { 995a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian // make sure we AT LEAST have the usage flags we want 996a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian if (mDirty || buffer==0 || 997a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian ((buffer->usage & mUsage) != mUsage)) { 998a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian mDirty = 0; 999a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return false; 1000a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian } 1001a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian return true; 1002a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 1003a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 1004a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ---------------------------------------------------------------------------- 1005edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 1006edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1007