Surface.cpp revision 3330b203039dea366d4981db1408a460134b2d2c
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> 28cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <utils/CallStack.h> 29c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h> 343330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 353330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferMapper.h> 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurface.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Surface.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/SurfaceComposerClient.h> 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h> 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 417189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian#include <pixelflinger/pixelflinger.h> 42076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 43cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <private/ui/SharedBufferStack.h> 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/LayerState.h> 45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------- 49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5014998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt( 513330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& dst, 523330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& src, 530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const Region& reg) 54076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 5514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian status_t err; 5614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t const * src_bits = NULL; 5714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); 5814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking src buffer %s", strerror(-err)); 590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6014998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t* dst_bits = NULL; 6114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); 6214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); 6314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 6414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator head(reg.begin()); 6514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator tail(reg.end()); 6614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (head != tail && src_bits && dst_bits) { 67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // NOTE: dst and src must be the same format 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, 10762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const ISurfaceFlingerClient::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) { 15462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 15501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 15662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setLayer(mToken, layer); 15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) { 16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 16201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setPosition(mToken, x, y); 16662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) { 16862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 16901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setSize(mToken, w, h); 17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 17462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() { 17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 17601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->hide(mToken); 18062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) { 18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 18301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 18662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->show(mToken, layer); 18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() { 18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 19001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 19262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->freeze(mToken); 19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() { 19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 19701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 19862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->unfreeze(mToken); 20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { 20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 20401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFlags(mToken, flags, mask); 20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { 21062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setTransparentRegionHint(mToken, transparent); 21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 21662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) { 21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 22062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setAlpha(mToken, alpha); 22262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 22501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 22662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); 22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) { 23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 23201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFreezeTint(mToken, tint); 23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 238cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianstatus_t SurfaceControl::validate(SharedClient const* cblk) const 23962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 24062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mToken<0 || mClient==0) { 24162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 24262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, mClient.get()); 24362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 24462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 24562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (cblk == 0) { 24662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); 24762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 24862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 24962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = cblk->validate(mToken); 25062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err != NO_ERROR) { 25162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", 25262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, err, strerror(-err)); 25362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return err; 25462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 255cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian uint32_t identity = cblk->getIdentity(mToken); 256cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mIdentity != identity) { 25762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("using an invalid surface id=%d, identity=%u should be %d", 258cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mToken, mIdentity, identity); 25962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 26062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 26162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_ERROR; 26262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 26362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 26401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel( 26501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& control, Parcel* parcel) 26601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 26701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t flags = 0; 26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t format = 0; 26901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian SurfaceID token = -1; 27001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t identity = 0; 271cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t width = 0; 272cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t height = 0; 27301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sp<SurfaceComposerClient> client; 27401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sp<ISurface> sur; 27501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (SurfaceControl::isValid(control)) { 27601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian token = control->mToken; 27701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian identity = control->mIdentity; 27801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian client = control->mClient; 27901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sur = control->mSurface; 280cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian width = control->mWidth; 281cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian height = control->mHeight; 28201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian format = control->mFormat; 28301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian flags = control->mFlags; 28401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 28501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); 28601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 28701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(token); 28801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(identity); 289cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(width); 290cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(height); 29101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(format); 29201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(flags); 29301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return NO_ERROR; 29401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 29501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 29601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const 29701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 29801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian Mutex::Autolock _l(mLock); 29901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (mSurfaceData == 0) { 30001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mSurfaceData = new Surface(const_cast<SurfaceControl*>(this)); 30101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 30201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return mSurfaceData; 30301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 30401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 305076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 306076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// Surface 307076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30901b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface) 31001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian : mClient(surface->mClient), mSurface(surface->mSurface), 31101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mToken(surface->mToken), mIdentity(surface->mIdentity), 3120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mFormat(surface->mFormat), mFlags(surface->mFlags), 3133330b203039dea366d4981db1408a460134b2d2cMathias Agopian mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), 314ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian mWidth(surface->mWidth), mHeight(surface->mHeight) 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mSharedBufferClient = new SharedBufferClient( 317cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mClient->mControl, mToken, 2); 318cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 31901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 32001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 32162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 32201b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const Parcel& parcel) 3233330b203039dea366d4981db1408a460134b2d2cMathias Agopian : mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL) 32401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 32501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sp<IBinder> clientBinder = parcel.readStrongBinder(); 32601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); 32701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mToken = parcel.readInt32(); 32801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mIdentity = parcel.readInt32(); 329cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth = parcel.readInt32(); 330cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mHeight = parcel.readInt32(); 33101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFormat = parcel.readInt32(); 33201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFlags = parcel.readInt32(); 33301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 334cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // FIXME: what does that mean if clientBinder is NULL here? 335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (clientBinder != NULL) { 33601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mClient = SurfaceComposerClient::clientForConnection(clientBinder); 33701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 338cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mSharedBufferClient = new SharedBufferClient( 339cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mClient->mControl, mToken, 2); 340cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 34201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 34301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 34401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 34501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init() 34601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 347076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::setSwapInterval = setSwapInterval; 348076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::dequeueBuffer = dequeueBuffer; 349076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::lockBuffer = lockBuffer; 350076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::queueBuffer = queueBuffer; 351cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian android_native_window_t::query = query; 3525221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian android_native_window_t::perform = perform; 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle.makeInvalid(); 354076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian DisplayInfo dinfo; 355076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceComposerClient::getDisplayInfo(0, &dinfo); 356076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi; 357076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi; 358076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: set real values here 359076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::minSwapInterval) = 1; 360076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::maxSwapInterval) = 1; 361076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<uint32_t&>(android_native_window_t::flags) = 0; 3625221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian // be default we request a hardware surface 3635221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian mUsage = GRALLOC_USAGE_HW_RENDER; 364cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mNeedFullUpdate = false; 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface() 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 36940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // this is a client-side operation, the surface is destroyed, unmap 37040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // its buffers in this process. 37140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian for (int i=0 ; i<2 ; i++) { 37250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) { 37321c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian getBufferMapper().unregisterBuffer(mBuffers[i]->handle); 37440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 37540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 37640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 37740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // clear all references and trigger an IPC now, to make sure things 37840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // happen without delay, since these resources are quite heavy. 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mClient.clear(); 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurface.clear(); 381cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian delete mSharedBufferClient; 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->flushCommands(); 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 385ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopiansp<SurfaceComposerClient> Surface::getClient() const { 386ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian return mClient; 387ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 388ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 389ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopiansp<ISurface> Surface::getISurface() const { 390ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian return mSurface; 391ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 392ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 393ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianbool Surface::isValid() { 394ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian return mToken>=0 && mClient!=0; 395ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 396ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 397cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianstatus_t Surface::validate(SharedClient const* cblk) const 398076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 399ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian sp<SurfaceComposerClient> client(getClient()); 40040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (mToken<0 || mClient==0) { 40140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 402ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian mToken, mIdentity, client.get()); 40340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return NO_INIT; 40440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 405076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (cblk == 0) { 406076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); 407076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 408076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 409076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = cblk->validate(mToken); 410076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) { 411076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", 412076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mToken, mIdentity, err, strerror(-err)); 413076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 414076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 415cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian uint32_t identity = cblk->getIdentity(mToken); 416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mIdentity != identity) { 417076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("using an invalid surface id=%d, identity=%u should be %d", 418cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mToken, mIdentity, identity); 419076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 420076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 422076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 423076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 42401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 42501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool Surface::isSameSurface( 42601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<Surface>& lhs, const sp<Surface>& rhs) 42701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 42801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (lhs == 0 || rhs == 0) 42901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return false; 430ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 43101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 43201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 43301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 434076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 435076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 436cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval) { 437076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 438076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 440076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window, 441cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian android_native_buffer_t** buffer) { 442076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->dequeueBuffer(buffer); 444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 445076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window, 447cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian android_native_buffer_t* buffer) { 448076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 449076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->lockBuffer(buffer); 450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window, 453cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian android_native_buffer_t* buffer) { 454076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->queueBuffer(buffer); 456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 458cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(android_native_window_t* window, 459cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int what, int* value) { 460cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian Surface* self = getSelf(window); 461cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return self->query(what, value); 462cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 463cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 4645221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(android_native_window_t* window, 465cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int operation, ...) { 4665221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_list args; 4675221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_start(args, operation); 4685221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian Surface* self = getSelf(window); 4695221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian int res = self->perform(operation, args); 4705221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_end(args); 4715221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian return res; 4725221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian} 4735221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian 474076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 4763330b203039dea366d4981db1408a460134b2d2cMathias Agopianstatus_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) { 4770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian android_native_buffer_t* out; 4780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t err = dequeueBuffer(&out); 479ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian if (err == NO_ERROR) { 4803330b203039dea366d4981db1408a460134b2d2cMathias Agopian *buffer = GraphicBuffer::getSelf(out); 481ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian } 4820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return err; 4830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 4840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 4850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian// ---------------------------------------------------------------------------- 4860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 487cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 488076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer) 489076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 490ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian sp<SurfaceComposerClient> client(getClient()); 491cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = validate(client->mControl); 492076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 493076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 495cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian ssize_t bufIdx = mSharedBufferClient->dequeue(); 496cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (bufIdx < 0) { 497cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE("error dequeuing a buffer (%s)", strerror(bufIdx)); 498cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return bufIdx; 49904bc12bd4316e2928134037cd0f81c6d8b2adcc8Mathias Agopian } 50068a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian 50168a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian // below we make sure we AT LEAST have the usage flags we want 50268a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian const uint32_t usage(getUsage()); 5033330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]); 50468a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian if (backBuffer == 0 || 50568a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian ((uint32_t(backBuffer->usage) & usage) != usage) || 50668a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian mSharedBufferClient->needNewBuffer(bufIdx)) 50768a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian { 508cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = getBufferLocked(bufIdx, usage); 509cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)", 510cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian bufIdx, usage, strerror(-err)); 51150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (err == NO_ERROR) { 51250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian // reset the width/height with the what we get from the buffer 51350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian mWidth = uint32_t(backBuffer->width); 51450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian mHeight = uint32_t(backBuffer->height); 51550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian } 516076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 517076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 518cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // if we still don't have a buffer here, we probably ran out of memory 519cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (!err && backBuffer==0) { 520cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = NO_MEMORY; 521cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 522cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 523cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian if (err == NO_ERROR) { 524cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mDirtyRegion.set(backBuffer->width, backBuffer->height); 525cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *buffer = backBuffer.get(); 526cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } else { 527cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mSharedBufferClient->undoDequeue(bufIdx); 528cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian } 52950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian 530cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian return err; 531076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 532076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 533076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer) 534076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 535ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian sp<SurfaceComposerClient> client(getClient()); 536cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = validate(client->mControl); 53740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (err != NO_ERROR) 53840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return err; 53940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 5403330b203039dea366d4981db1408a460134b2d2cMathias Agopian int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex(); 541cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = mSharedBufferClient->lock(bufIdx); 542cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err)); 543cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return err; 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer) 547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 548ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian sp<SurfaceComposerClient> client(getClient()); 549cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = validate(client->mControl); 550076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 551076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 552076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (mSwapRectangle.isValid()) { 5540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mDirtyRegion.set(mSwapRectangle); 5550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 5560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 5573330b203039dea366d4981db1408a460134b2d2cMathias Agopian int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex(); 558cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); 559cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = mSharedBufferClient->queue(bufIdx); 560cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err)); 561076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 562cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (err == NO_ERROR) { 563cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // FIXME: can we avoid this IPC if we know there is one pending? 564ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian client->signalServer(); 565cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 566cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return err; 567076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 569cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value) 570cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{ 571cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian switch (what) { 572cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case NATIVE_WINDOW_WIDTH: 573cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *value = int(mWidth); 574cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 575cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case NATIVE_WINDOW_HEIGHT: 576cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *value = int(mHeight); 577cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian case NATIVE_WINDOW_FORMAT: 579cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian *value = int(mFormat); 580cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 581cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian } 582cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return BAD_VALUE; 583cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 584cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 5855221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(int operation, va_list args) 5865221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{ 5875221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian int res = NO_ERROR; 5885221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian switch (operation) { 5895221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian case NATIVE_WINDOW_SET_USAGE: 590ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian setUsage( va_arg(args, int) ); 5915221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian break; 5925221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian default: 5935221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian res = NAME_NOT_FOUND; 5945221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian break; 5955221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian } 5965221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian return res; 5975221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian} 5985221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian 599ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianvoid Surface::setUsage(uint32_t reqUsage) 600ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian{ 601ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 60268a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian mUsage = reqUsage; 603ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 604ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 60568a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopianuint32_t Surface::getUsage() const 606cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian{ 607cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian Mutex::Autolock _l(mSurfaceLock); 60868a6afeb26002961387573dd64dd0ea3816bdc91Mathias Agopian return mUsage; 609cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian} 610cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 611076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 612076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) { 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return Surface::lock(info, NULL, blocking); 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 618076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 619cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mApiLock.tryLock() != NO_ERROR) { 620cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE("calling Surface::lock() from different threads!"); 621cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian CallStack stack; 622cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian stack.update(); 623cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian stack.dump("Surface::lock called from different threads"); 624cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return WOULD_BLOCK; 625cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 626cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 6275221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian // we're intending to do software rendering from this point 628ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 629ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 6303330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> backBuffer; 631076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = dequeueBuffer(&backBuffer); 632cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); 633076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 634cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = lockBuffer(backBuffer.get()); 635cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)", 636cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian backBuffer->getIndex(), strerror(-err)); 637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we handle copy-back here... 639cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 640076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Rect bounds(backBuffer->width, backBuffer->height); 6410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Region scratch(bounds); 6420926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); 643076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 644cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mNeedFullUpdate) { 645cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // reset newDirtyRegion to bounds when a buffer is reallocated 646cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // it would be better if this information was associated with 647cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // the buffer and made available to outside of Surface. 648cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // This will do for now though. 649cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mNeedFullUpdate = false; 650076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian newDirtyRegion.set(bounds); 6510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 6520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian newDirtyRegion.andSelf(bounds); 653cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 654cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 6553330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); 656cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (frontBuffer !=0 && 657cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian backBuffer->width == frontBuffer->width && 658cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian backBuffer->height == frontBuffer->height && 659cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian !(mFlags & ISurfaceComposer::eDestroyBackbuffer)) 660cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian { 661cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); 662cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (!copyback.isEmpty() && frontBuffer!=0) { 663cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian // copy front to back 664cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian copyBlt(backBuffer, frontBuffer, copyback); 665076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 666076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 667cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 6680926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mDirtyRegion = newDirtyRegion; 6690926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mOldDirtyRegion = newDirtyRegion; 670076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 671e71212ba5397387100a578d23b15862518a7a859Mathias Agopian void* vaddr; 6720926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t res = backBuffer->lock( 6730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 674e71212ba5397387100a578d23b15862518a7a859Mathias Agopian newDirtyRegion.bounds(), &vaddr); 6750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 676cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGW_IF(res, "failed locking buffer (handle = %p)", 677cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian backBuffer->handle); 6780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mLockedBuffer = backBuffer; 6800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->w = backBuffer->width; 6810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->h = backBuffer->height; 6820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->s = backBuffer->stride; 6830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->usage = backBuffer->usage; 6840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->format = backBuffer->format; 685e71212ba5397387100a578d23b15862518a7a859Mathias Agopian other->bits = vaddr; 686076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 687076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 688cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mApiLock.unlock(); 689076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 690edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 691076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 692076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost() 693076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 694cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mLockedBuffer == 0) { 695cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE("unlockAndPost failed, no locked buffer"); 696076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return BAD_VALUE; 697cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 698edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 699cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = mLockedBuffer->unlock(); 700cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); 7010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 702cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian err = queueBuffer(mLockedBuffer.get()); 703cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)", 704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mLockedBuffer->getIndex(), strerror(-err)); 705cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 706cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mPostedBuffer = mLockedBuffer; 707076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer = 0; 708076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 709edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 710edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 711edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) { 712ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 713edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle = r; 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 7165221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianstatus_t Surface::getBufferLocked(int index, int usage) 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 718ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian sp<ISurface> s(mSurface); 719ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian if (s == 0) return NO_INIT; 720ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 721076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = NO_MEMORY; 72250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian 72350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian // free the current buffer 7243330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer>& currentBuffer(mBuffers[index]); 72550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (currentBuffer != 0) { 72650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian getBufferMapper().unregisterBuffer(currentBuffer->handle); 72750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian currentBuffer.clear(); 72850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian } 72950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian 7303330b203039dea366d4981db1408a460134b2d2cMathias Agopian sp<GraphicBuffer> buffer = s->requestBuffer(index, usage); 731cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(buffer==0, 732cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian "ISurface::getBuffer(%d, %08x) returned NULL", 733cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian index, usage); 73450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (buffer != 0) { // this should never happen by construction 735cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(buffer->handle == NULL, 7360b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian "Surface (identity=%d) requestBuffer(%d, %08x) returned" 7370b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian "a buffer with a null handle", mIdentity, index, usage); 7380b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian err = mSharedBufferClient->getStatus(); 7390b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian LOGE_IF(err, "Surface (identity=%d) state = %d", mIdentity, err); 7400b3ad46a26dc3717260fa9347c77f673f3198606Mathias Agopian if (!err && buffer->handle != NULL) { 74150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian err = getBufferMapper().registerBuffer(buffer->handle); 74250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian LOGW_IF(err, "registerBuffer(...) failed %d (%s)", 74350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian err, strerror(-err)); 74450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian if (err == NO_ERROR) { 74550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian currentBuffer = buffer; 746cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian currentBuffer->setIndex(index); 747cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mNeedFullUpdate = true; 74850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian } 749edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 750edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 751076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 752edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 753edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 754edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 755edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 756