Surface.cpp revision a67932fe6864ac346e7f78b86df11cf6c5344137
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 24cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <utils/CallStack.h> 25a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <utils/Errors.h> 269cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <utils/Log.h> 27a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <utils/threads.h> 289cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian 29c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h> 30a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <binder/IPCThreadState.h> 31a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 32a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <gui/SurfaceTextureClient.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h> 353330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBuffer.h> 363330b203039dea366d4981db1408a460134b2d2cMathias Agopian#include <ui/GraphicBufferMapper.h> 3735b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian#include <ui/GraphicLog.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h> 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 409cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurface.h> 419cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/ISurfaceComposer.h> 42a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian#include <surfaceflinger/Surface.h> 439cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <surfaceflinger/SurfaceComposerClient.h> 44076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 459cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian#include <private/surfaceflinger/LayerState.h> 46076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------- 50076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5114998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt( 523330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& dst, 533330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& src, 540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const Region& reg) 55076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 56245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // src and dst with, height and format must be identical. no verification 57245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // is done here. 5814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian status_t err; 5914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t const * src_bits = NULL; 6014998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); 6114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking src buffer %s", strerror(-err)); 620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t* dst_bits = NULL; 6414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); 6514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); 6614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 6714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator head(reg.begin()); 6814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator tail(reg.end()); 6914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (head != tail && src_bits && dst_bits) { 70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t bpp = bytesPerPixel(src->format); 71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t dbpr = dst->stride * bpp; 72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t sbpr = src->stride * bpp; 730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 7414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian while (head != tail) { 7514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian const Rect& r(*head++); 760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian ssize_t h = r.height(); 770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (h <= 0) continue; 780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian size_t size = r.width() * bpp; 790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; 800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; 810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (dbpr==sbpr && size==sbpr) { 820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian size *= h; 830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian h = 1; 84076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian do { 860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian memcpy(d, s, size); 870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian d += dbpr; 880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian s += sbpr; 890926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } while (--h > 0); 90076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 91076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 920926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 9314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (src_bits) 9414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian src->unlock(); 9514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 9614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (dst_bits) 9714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian dst->unlock(); 9814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 9914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian return err; 100076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 101076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 10262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 10362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// SurfaceControl 10462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 10562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 10601b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurfaceControl::SurfaceControl( 10701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceComposerClient>& client, 10862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<ISurface>& surface, 1097e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian const ISurfaceComposerClient::surface_data_t& data, 11018d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) 11162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian : mClient(client), mSurface(surface), 11262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken(data.token), mIdentity(data.identity), 1131c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian mWidth(data.width), mHeight(data.height), mFormat(data.format), 1141c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian mFlags(flags) 11562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 11662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 11718d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian 11862185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl() 11962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 12062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 12162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 12262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 12362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy() 12462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 12518d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian if (isValid()) { 12662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient->destroySurface(mToken); 12762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 12862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 12962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // clear all references and trigger an IPC now, to make sure things 13062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // happen without delay, since these resources are quite heavy. 13162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient.clear(); 13262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurface.clear(); 13362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian IPCThreadState::self()->flushCommands(); 13462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 13562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 13662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear() 13762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 13862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // here, the window manager tells us explicitly that we should destroy 13962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // the surface's resource. Soon after this call, it will also release 14062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // its last reference (which will call the dtor); however, it is possible 14162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // that a client living in the same process still holds references which 14262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // would delay the call to the dtor -- that is why we need this explicit 14362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // "clear()" call. 14462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 14562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 14662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 14701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool SurfaceControl::isSameSurface( 14801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 14901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 15001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (lhs == 0 || rhs == 0) 15101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return false; 15201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 15301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 15401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 15562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) { 156963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 158631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setLayer(mToken, layer); 16062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) { 162963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 164631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setPosition(mToken, x, y); 16662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) { 168963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 16962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 170631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setSize(mToken, w, h); 17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() { 174963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 176631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->hide(mToken); 17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) { 180963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 182631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 18362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->show(mToken, layer); 18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() { 186963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 188631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->freeze(mToken); 19062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() { 192963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 194631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->unfreeze(mToken); 19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 19762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { 198963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 200631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFlags(mToken, flags, mask); 20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { 204963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 206631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setTransparentRegionHint(mToken, transparent); 20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) { 210963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 21162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 212631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setAlpha(mToken, alpha); 21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 216963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 218631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); 22062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) { 222963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopian status_t err = validate(); 22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 224631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian const sp<SurfaceComposerClient>& client(mClient); 22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFreezeTint(mToken, tint); 22662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 228963abad79ae64dae9bf4c32bfb110d9e6314c857Mathias Agopianstatus_t SurfaceControl::validate() const 22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mToken<0 || mClient==0) { 23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, mClient.get()); 23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_ERROR; 23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 23801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel( 23901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& control, Parcel* parcel) 24001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 241579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<ISurface> sur; 24201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t identity = 0; 243cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t width = 0; 244cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t height = 0; 245579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t format = 0; 246579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t flags = 0; 24701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (SurfaceControl::isValid(control)) { 24801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sur = control->mSurface; 249579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian identity = control->mIdentity; 250cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian width = control->mWidth; 251cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian height = control->mHeight; 25201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian format = control->mFormat; 25301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian flags = control->mFlags; 25401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 255b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 25601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(identity); 257cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(width); 258cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(height); 25901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(format); 26001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(flags); 26101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return NO_ERROR; 26201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 26301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 26401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const 26501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 26601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian Mutex::Autolock _l(mLock); 26701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (mSurfaceData == 0) { 26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mSurfaceData = new Surface(const_cast<SurfaceControl*>(this)); 26901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 27001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return mSurfaceData; 27101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 27201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 273076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 274076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// Surface 275076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 277b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian// --------------------------------------------------------------------------- 278b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian 27901b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface) 280a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : mInitCheck(NO_INIT), 281b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mSurface(surface->mSurface), 282b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mIdentity(surface->mIdentity), 283b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian mFormat(surface->mFormat), mFlags(surface->mFlags), 284ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian mWidth(surface->mWidth), mHeight(surface->mHeight) 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 28601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 28701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 28862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 289a0c30e924193da57723fd53b710ce6be24fb26f5Mathias AgopianSurface::Surface(const Parcel& parcel, const sp<IBinder>& ref) 290a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian : mInitCheck(NO_INIT) 29101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 292a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian mSurface = interface_cast<ISurface>(ref); 29301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mIdentity = parcel.readInt32(); 294cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth = parcel.readInt32(); 295cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mHeight = parcel.readInt32(); 29601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFormat = parcel.readInt32(); 29701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFlags = parcel.readInt32(); 29801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 29901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 30001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 301579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopianstatus_t Surface::writeToParcel( 302579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian const sp<Surface>& surface, Parcel* parcel) 303579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian{ 304579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sp<ISurface> sur; 305579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t identity = 0; 306579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t width = 0; 307579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t height = 0; 308579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t format = 0; 309579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian uint32_t flags = 0; 310579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian if (Surface::isValid(surface)) { 311579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian sur = surface->mSurface; 312579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian identity = surface->mIdentity; 313579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian width = surface->mWidth; 314579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian height = surface->mHeight; 315579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian format = surface->mFormat; 316579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian flags = surface->mFlags; 31789c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis } else if (surface != 0 && surface->mSurface != 0) { 31889c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis LOGW("Parceling invalid surface with non-NULL ISurface as NULL: " 31989c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis "mSurface = %p, mIdentity = %d, mWidth = %d, mHeight = %d, " 32089c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis "mFormat = %d, mFlags = 0x%08x, mInitCheck = %d", 32189c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis surface->mSurface.get(), surface->mIdentity, surface->mWidth, 32289c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis surface->mHeight, surface->mFormat, surface->mFlags, 32389c2dd2cc27ead77da131fe27810c99a11a92ad7Jamie Gennis surface->mInitCheck); 324579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian } 325579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 326579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(identity); 327579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(width); 328579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(height); 329579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(format); 330579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian parcel->writeInt32(flags); 331579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian return NO_ERROR; 332579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 333579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian} 334579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian 335aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie GennisMutex Surface::sCachedSurfacesLock; 336455d18d4c26a823bff62ca14771986cca52d3462Mathias AgopianDefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces; 337aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis 338aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennissp<Surface> Surface::readFromParcel(const Parcel& data) { 339aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis Mutex::Autolock _l(sCachedSurfacesLock); 340a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian sp<IBinder> binder(data.readStrongBinder()); 341aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote(); 342aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis if (surface == 0) { 343aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis surface = new Surface(data, binder); 344aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis sCachedSurfaces.add(binder, surface); 345aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis } 346aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis if (surface->mSurface == 0) { 347aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis surface = 0; 348aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis } 349455d18d4c26a823bff62ca14771986cca52d3462Mathias Agopian cleanCachedSurfacesLocked(); 350aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis return surface; 351aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis} 352aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis 353aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis// Remove the stale entries from the surface cache. This should only be called 354aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis// with sCachedSurfacesLock held. 355455d18d4c26a823bff62ca14771986cca52d3462Mathias Agopianvoid Surface::cleanCachedSurfacesLocked() { 356aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis for (int i = sCachedSurfaces.size()-1; i >= 0; --i) { 357aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis wp<Surface> s(sCachedSurfaces.valueAt(i)); 358aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis if (s == 0 || s.promote() == 0) { 359aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis sCachedSurfaces.removeItemsAt(i); 360aca4e2287939b4ce3d9e9aced64c5c9641333503Jamie Gennis } 361a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian } 362a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian} 363a0c30e924193da57723fd53b710ce6be24fb26f5Mathias Agopian 36401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init() 36501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 3664b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::setSwapInterval = setSwapInterval; 3674b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::dequeueBuffer = dequeueBuffer; 36819957553cbda9134f542e3374c28710d3556d1ceMathias Agopian ANativeWindow::cancelBuffer = cancelBuffer; 3694b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::lockBuffer = lockBuffer; 3704b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::queueBuffer = queueBuffer; 3714b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::query = query; 3724b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn ANativeWindow::perform = perform; 373631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 374a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mSurface != NULL) { 375a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian sp<ISurfaceTexture> surfaceTexture(mSurface->getSurfaceTexture()); 376a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface"); 377a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (surfaceTexture != NULL) { 378a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTextureClient = new SurfaceTextureClient(surfaceTexture); 379a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTextureClient->setUsage(GraphicBuffer::USAGE_HW_RENDER); 380a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian } 381a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 382a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian DisplayInfo dinfo; 383a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian SurfaceComposerClient::getDisplayInfo(0, &dinfo); 384a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi; 385a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi; 386a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 387a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const_cast<int&>(ANativeWindow::minSwapInterval) = 388a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTextureClient->minSwapInterval; 389a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 390a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const_cast<int&>(ANativeWindow::maxSwapInterval) = 391a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTextureClient->maxSwapInterval; 392a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 393a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian const_cast<uint32_t&>(ANativeWindow::flags) = 0; 394a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian 395a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian if (mSurfaceTextureClient != 0) { 396a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mInitCheck = NO_ERROR; 397b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian } 398631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian } 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface() 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 40340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // clear all references and trigger an IPC now, to make sure things 40440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // happen without delay, since these resources are quite heavy. 405a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTextureClient.clear(); 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurface.clear(); 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->flushCommands(); 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 410ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianbool Surface::isValid() { 411631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian return mInitCheck == NO_ERROR; 412ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian} 413ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 414a317f1ba7f71fe04d524f46dbdc6e2419b7f75a3Mathias Agopianstatus_t Surface::validate(bool inCancelBuffer) const 415076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 416631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian // check that we initialized ourself properly 417631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian if (mInitCheck != NO_ERROR) { 418579b3f88d03d06b897b778bd11818f5104677d1dMathias Agopian LOGE("invalid token (identity=%u)", mIdentity); 419631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian return mInitCheck; 42040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 422076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 423076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 42447d8730a2463f38a695ab95b533b0d9728f266a3Mathias Agopiansp<IBinder> Surface::asBinder() const { 42547d8730a2463f38a695ab95b533b0d9728f266a3Mathias Agopian return mSurface!=0 ? mSurface->asBinder() : 0; 426631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian} 427631f358d348ea5e7813ca01f86fc9f2a6536add6Mathias Agopian 428076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 429076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 4304b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::setSwapInterval(ANativeWindow* window, int interval) { 431a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian Surface* self = getSelf(window); 432a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return self->setSwapInterval(interval); 433076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 434076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 4354b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::dequeueBuffer(ANativeWindow* window, 436697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer** buffer) { 437076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 438076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->dequeueBuffer(buffer); 439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 440076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 44119957553cbda9134f542e3374c28710d3556d1ceMathias Agopianint Surface::cancelBuffer(ANativeWindow* window, 442697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* buffer) { 44319957553cbda9134f542e3374c28710d3556d1ceMathias Agopian Surface* self = getSelf(window); 44419957553cbda9134f542e3374c28710d3556d1ceMathias Agopian return self->cancelBuffer(buffer); 44519957553cbda9134f542e3374c28710d3556d1ceMathias Agopian} 44619957553cbda9134f542e3374c28710d3556d1ceMathias Agopian 4474b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::lockBuffer(ANativeWindow* window, 448697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* buffer) { 449076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->lockBuffer(buffer); 451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 4534b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::queueBuffer(ANativeWindow* window, 454697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* buffer) { 455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->queueBuffer(buffer); 457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 45941abd67302b52aefadc2b3dea42226f16bf6d9baIliyan Malchevint Surface::query(const ANativeWindow* window, 460cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int what, int* value) { 46141abd67302b52aefadc2b3dea42226f16bf6d9baIliyan Malchev const Surface* self = getSelf(window); 462cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return self->query(what, value); 463cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 464cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 4654b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackbornint Surface::perform(ANativeWindow* window, 466cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian int operation, ...) { 4675221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_list args; 4685221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_start(args, operation); 4695221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian Surface* self = getSelf(window); 4705221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian int res = self->perform(operation, args); 4715221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian va_end(args); 4725221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian return res; 4735221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian} 4745221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian 475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 477a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::setSwapInterval(int interval) { 478a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->setSwapInterval(interval); 479a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 480a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 481a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::dequeueBuffer(ANativeWindowBuffer** buffer) { 482a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian status_t err = mSurfaceTextureClient->dequeueBuffer(buffer); 483cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian if (err == NO_ERROR) { 484a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mDirtyRegion.set(buffer[0]->width, buffer[0]->height); 485cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian } 486cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian return err; 487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 488076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 489a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::cancelBuffer(ANativeWindowBuffer* buffer) { 490a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->cancelBuffer(buffer); 49119957553cbda9134f542e3374c28710d3556d1ceMathias Agopian} 49219957553cbda9134f542e3374c28710d3556d1ceMathias Agopian 493a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::lockBuffer(ANativeWindowBuffer* buffer) { 494a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->lockBuffer(buffer); 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 497a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::queueBuffer(ANativeWindowBuffer* buffer) { 498a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->queueBuffer(buffer); 499076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 501a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::query(int what, int* value) const { 502cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian switch (what) { 503a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: 504a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // TODO: this is not needed anymore 505a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian *value = 1; 506cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return NO_ERROR; 507391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis case NATIVE_WINDOW_CONCRETE_TYPE: 508a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian // TODO: this is not needed anymore 509391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis *value = NATIVE_WINDOW_SURFACE; 510391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis return NO_ERROR; 511391bbe2246a7547dbf3460c231b3c5ba691d4eb1Jamie Gennis } 512a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->query(what, value); 513cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian} 514cc08e688f5b82b4ebd076ad138b2749e8c86ad5eMathias Agopian 515a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::perform(int operation, va_list args) { 516a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->perform(operation, args); 5171d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 5181d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 519a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ---------------------------------------------------------------------------- 520a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian 521a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopianint Surface::getConnectedApi() const { 522a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian return mSurfaceTextureClient->getConnectedApi(); 523a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian} 52455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 525076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 526076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) { 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return Surface::lock(info, NULL, blocking); 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 5310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 532076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 53355fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian if (getConnectedApi()) { 53455fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian LOGE("Surface::lock(%p) failed. Already connected to another API", 5354b5e91e4820f03dba7dcc36e4b148331bc964b4bDianne Hackborn (ANativeWindow*)this); 53655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian CallStack stack; 53755fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian stack.update(); 53855fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian stack.dump(""); 53955fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian return INVALID_OPERATION; 54055fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian } 54155fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian 542cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mApiLock.tryLock() != NO_ERROR) { 5439014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian LOGE("calling Surface::lock from different threads!"); 544cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian CallStack stack; 545cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian stack.update(); 54655fa25161a7626ae6a15bc2cc46e22771455ed80Mathias Agopian stack.dump(""); 547cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian return WOULD_BLOCK; 548cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 5499014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian 5509014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian /* Here we're holding mApiLock */ 551cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 5529014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian if (mLockedBuffer != 0) { 5539014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian LOGE("Surface::lock failed, already locked"); 5549014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian mApiLock.unlock(); 5559014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian return INVALID_OPERATION; 5569014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian } 5579014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian 5585221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian // we're intending to do software rendering from this point 559a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mSurfaceTextureClient->setUsage( 560a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 561ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian 562697526bc9e44ce61c88614f98387ae8bbf0a187eIliyan Malchev ANativeWindowBuffer* out; 563a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian status_t err = mSurfaceTextureClient->dequeueBuffer(&out); 564cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); 565076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 566b296533607232357597b255679db29470ab5925dMathias Agopian sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); 567a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian err = mSurfaceTextureClient->lockBuffer(backBuffer.get()); 568a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)", 569a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian backBuffer->handle, strerror(-err)); 570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 571076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Rect bounds(backBuffer->width, backBuffer->height); 572245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian const Region boundsRegion(bounds); 573245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian Region scratch(boundsRegion); 5740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); 575245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian newDirtyRegion &= boundsRegion; 576076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 577245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // figure out if we can copy the frontbuffer back 5783330b203039dea366d4981db1408a460134b2d2cMathias Agopian const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); 579245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian const bool canCopyBack = (frontBuffer != 0 && 580245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian backBuffer->width == frontBuffer->width && 581245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian backBuffer->height == frontBuffer->height && 582245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian backBuffer->format == frontBuffer->format && 583245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian !(mFlags & ISurfaceComposer::eDestroyBackbuffer)); 584245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian 585245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // the dirty region we report to surfaceflinger is the one 586245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // given by the user (as opposed to the one *we* return to the 587245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // user). 588245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian mDirtyRegion = newDirtyRegion; 589245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian 590245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian if (canCopyBack) { 591245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // copy the area that is invalid and not repainted this round 592245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); 593245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian if (!copyback.isEmpty()) 594cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian copyBlt(backBuffer, frontBuffer, copyback); 595245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian } else { 596245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // if we can't copy-back anything, modify the user's dirty 597245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // region to make sure they redraw the whole buffer 598245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian newDirtyRegion = boundsRegion; 599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 600cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 601245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // keep track of the are of the buffer that is "clean" 602245e4d78c5fb304fe153c36303ec69bf8a907f65Mathias Agopian // (ie: that will be redrawn) 6030926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mOldDirtyRegion = newDirtyRegion; 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 605e71212ba5397387100a578d23b15862518a7a859Mathias Agopian void* vaddr; 6060926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t res = backBuffer->lock( 6070926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 608e71212ba5397387100a578d23b15862518a7a859Mathias Agopian newDirtyRegion.bounds(), &vaddr); 6090926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 610cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGW_IF(res, "failed locking buffer (handle = %p)", 611cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian backBuffer->handle); 6120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6130926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mLockedBuffer = backBuffer; 6140926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->w = backBuffer->width; 6150926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->h = backBuffer->height; 6160926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->s = backBuffer->stride; 6170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->usage = backBuffer->usage; 6180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->format = backBuffer->format; 619e71212ba5397387100a578d23b15862518a7a859Mathias Agopian other->bits = vaddr; 620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 622cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mApiLock.unlock(); 623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 625076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 626076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost() 627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 628cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian if (mLockedBuffer == 0) { 6299014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian LOGE("Surface::unlockAndPost failed, no locked buffer"); 6309014726d8954a003323d65ba639b2544f8ecea2eMathias Agopian return INVALID_OPERATION; 631cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian } 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian status_t err = mLockedBuffer->unlock(); 634cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); 6350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 636a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian err = mSurfaceTextureClient->queueBuffer(mLockedBuffer.get()); 637a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", 638a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian mLockedBuffer->handle, strerror(-err)); 639cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian 640cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian mPostedBuffer = mLockedBuffer; 641076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer = 0; 642076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 643edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 644edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 645a138f89c5e78b7e8994823e97d6e860869762837Mathias Agopian// ---------------------------------------------------------------------------- 646edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 647