Surface.cpp revision cb6b9041647b4f080324742eee5ce709960ff610
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> 28c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h> 29c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h> 33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/BufferMapper.h> 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurface.h> 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Surface.h> 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/SurfaceComposerClient.h> 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h> 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 397189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian#include <pixelflinger/pixelflinger.h> 40076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/SharedState.h> 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/LayerState.h> 437189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian#include <private/ui/SurfaceBuffer.h> 44076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 47076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// SurfaceBuffer 49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 50076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 51076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::SurfaceBuffer() 5221c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian : BASE(), mOwner(false), mBufferMapper(BufferMapper::get()) 53076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 54076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian width = 55076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian height = 56076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian stride = 57076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian format = 58076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian usage = 0; 5921c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian handle = NULL; 60076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 61076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 62076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::SurfaceBuffer(const Parcel& data) 6321c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian : BASE(), mOwner(true), mBufferMapper(BufferMapper::get()) 64076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 65076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we own the handle in this case 66076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian width = data.readInt32(); 67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian height = data.readInt32(); 68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian stride = data.readInt32(); 69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian format = data.readInt32(); 70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian usage = data.readInt32(); 71076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian handle = data.readNativeHandle(); 72076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 73076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 74076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias AgopianSurfaceBuffer::~SurfaceBuffer() 75076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 76076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (handle && mOwner) { 77076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian native_handle_close(handle); 78076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian native_handle_delete(const_cast<native_handle*>(handle)); 79076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 80076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 81076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 82e71212ba5397387100a578d23b15862518a7a859Mathias Agopianstatus_t SurfaceBuffer::lock(uint32_t usage, void** vaddr) 830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const Rect lockBounds(width, height); 85e71212ba5397387100a578d23b15862518a7a859Mathias Agopian status_t res = lock(usage, lockBounds, vaddr); 860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return res; 870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 89e71212ba5397387100a578d23b15862518a7a859Mathias Agopianstatus_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) 900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 9114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (rect.left < 0 || rect.right > this->width || 9214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian rect.top < 0 || rect.bottom > this->height) { 9314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 9414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian rect.left, rect.top, rect.right, rect.bottom, 9514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian this->width, this->height); 9614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian return BAD_VALUE; 9714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian } 98e71212ba5397387100a578d23b15862518a7a859Mathias Agopian status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); 990926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return res; 1000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 1010926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 1020926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t SurfaceBuffer::unlock() 1030926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 1040926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t res = getBufferMapper().unlock(handle); 1050926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return res; 1060926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 1070926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 108076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t SurfaceBuffer::writeToParcel(Parcel* reply, 109076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t const* buffer) 110076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 111076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->width); 112076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->height); 113076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->stride); 114076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->format); 115076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reply->writeInt32(buffer->usage); 11621c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian reply->writeNativeHandle(buffer->handle); 117076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 118076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 119076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 120076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------- 121076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 12214998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt( 1230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const sp<SurfaceBuffer>& dst, 1240926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const sp<SurfaceBuffer>& src, 1250926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const Region& reg) 126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 12714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian status_t err; 12814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t const * src_bits = NULL; 12914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits); 13014998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking src buffer %s", strerror(-err)); 1310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 13214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian uint8_t* dst_bits = NULL; 13314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits); 13414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian LOGE_IF(err, "error locking dst buffer %s", strerror(-err)); 13514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 13614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator head(reg.begin()); 13714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian Region::const_iterator tail(reg.end()); 13814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (head != tail && src_bits && dst_bits) { 139076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // NOTE: dst and src must be the same format 140076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t bpp = bytesPerPixel(src->format); 141076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t dbpr = dst->stride * bpp; 142076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const size_t sbpr = src->stride * bpp; 1430926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 14414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian while (head != tail) { 14514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian const Rect& r(*head++); 1460926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian ssize_t h = r.height(); 1470926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (h <= 0) continue; 1480926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian size_t size = r.width() * bpp; 1490926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; 1500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; 1510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (dbpr==sbpr && size==sbpr) { 1520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian size *= h; 1530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian h = 1; 154076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 1550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian do { 1560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian memcpy(d, s, size); 1570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian d += dbpr; 1580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian s += sbpr; 1590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } while (--h > 0); 160076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 161076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 1620926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 16314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (src_bits) 16414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian src->unlock(); 16514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 16614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (dst_bits) 16714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian dst->unlock(); 16814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian 16914998596937791c8efdfd61411236a7c7f66c064Mathias Agopian return err; 170076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 171076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// SurfaceControl 17462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================ 17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 17601b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurfaceControl::SurfaceControl( 17701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceComposerClient>& client, 17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<ISurface>& surface, 17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const ISurfaceFlingerClient::surface_data_t& data, 18018d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) 18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian : mClient(client), mSurface(surface), 18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken(data.token), mIdentity(data.identity), 183cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth(w), mHeight(h), mFormat(format), mFlags(flags) 18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 18618d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian 18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl() 18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 19062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 19262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy() 19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 19418d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian if (isValid()) { 19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient->destroySurface(mToken); 19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 19762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 19862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // clear all references and trigger an IPC now, to make sure things 19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // happen without delay, since these resources are quite heavy. 20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mClient.clear(); 20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mSurface.clear(); 20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian IPCThreadState::self()->flushCommands(); 20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 20462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear() 20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // here, the window manager tells us explicitly that we should destroy 20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // the surface's resource. Soon after this call, it will also release 20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // its last reference (which will call the dtor); however, it is possible 21062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // that a client living in the same process still holds references which 21162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // would delay the call to the dtor -- that is why we need this explicit 21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian // "clear()" call. 21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian destroy(); 21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 21601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool SurfaceControl::isSameSurface( 21701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 21801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 21901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (lhs == 0 || rhs == 0) 22001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return false; 22101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 22201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 22301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) { 22562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 22601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setLayer(mToken, layer); 23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) { 23262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 23301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setPosition(mToken, x, y); 23762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 23862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) { 23962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 24001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 24162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 24262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 24362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setSize(mToken, w, h); 24462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 24562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() { 24662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 24701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 24862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 24962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 25062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->hide(mToken); 25162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 25262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) { 25362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 25401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 25562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 25662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 25762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->show(mToken, layer); 25862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 25962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() { 26062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 26101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 26262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 26362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 26462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->freeze(mToken); 26562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 26662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() { 26762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 26962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 27062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 27162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->unfreeze(mToken); 27262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 27362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) { 27462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 27501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 27662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 27762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 27862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFlags(mToken, flags, mask); 27962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 28062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) { 28162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 28201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 28362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 28462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 28562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setTransparentRegionHint(mToken, transparent); 28662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 28762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) { 28862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 28901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 29062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 29162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 29262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setAlpha(mToken, alpha); 29362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 29462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { 29562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 29601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 29762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 29862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 29962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy); 30062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 30162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) { 30262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian const sp<SurfaceComposerClient>& client(mClient); 30301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (client == 0) return NO_INIT; 30462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = validate(client->mControl); 30562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err < 0) return err; 30662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return client->setFreezeTint(mToken, tint); 30762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 30862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 30962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::validate(per_client_cblk_t const* cblk) const 31062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{ 31162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mToken<0 || mClient==0) { 31262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 31362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, mClient.get()); 31462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 31562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 31662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (cblk == 0) { 31762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); 31862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 31962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 32062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian status_t err = cblk->validate(mToken); 32162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (err != NO_ERROR) { 32262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", 32362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, err, strerror(-err)); 32462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return err; 32562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 32662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian if (mIdentity != uint32_t(cblk->layers[mToken].identity)) { 32762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian LOGE("using an invalid surface id=%d, identity=%u should be %d", 32862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian mToken, mIdentity, cblk->layers[mToken].identity); 32962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_INIT; 33062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian } 33162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian return NO_ERROR; 33262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian} 33362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 33401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel( 33501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<SurfaceControl>& control, Parcel* parcel) 33601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 33701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t flags = 0; 33801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t format = 0; 33901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian SurfaceID token = -1; 34001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian uint32_t identity = 0; 341cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t width = 0; 342cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian uint32_t height = 0; 34301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sp<SurfaceComposerClient> client; 34401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sp<ISurface> sur; 34501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (SurfaceControl::isValid(control)) { 34601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian token = control->mToken; 34701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian identity = control->mIdentity; 34801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian client = control->mClient; 34901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sur = control->mSurface; 350cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian width = control->mWidth; 351cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian height = control->mHeight; 35201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian format = control->mFormat; 35301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian flags = control->mFlags; 35401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 35501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); 35601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); 35701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(token); 35801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(identity); 359cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(width); 360cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian parcel->writeInt32(height); 36101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(format); 36201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian parcel->writeInt32(flags); 36301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return NO_ERROR; 36401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 36501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 36601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const 36701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 36801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian Mutex::Autolock _l(mLock); 36901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (mSurfaceData == 0) { 37001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mSurfaceData = new Surface(const_cast<SurfaceControl*>(this)); 37101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian } 37201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return mSurfaceData; 37301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 37401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 375076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 376076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// Surface 377076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================ 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 37901b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface) 38001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian : mClient(surface->mClient), mSurface(surface->mSurface), 38101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mToken(surface->mToken), mIdentity(surface->mIdentity), 382cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth(surface->mWidth), mHeight(surface->mHeight), 3830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mFormat(surface->mFormat), mFlags(surface->mFlags), 3840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mBufferMapper(BufferMapper::get()) 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 38601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 38701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 38862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian 38901b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const Parcel& parcel) 3900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian : mBufferMapper(BufferMapper::get()) 39101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 39201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian sp<IBinder> clientBinder = parcel.readStrongBinder(); 39301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); 39401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mToken = parcel.readInt32(); 39501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mIdentity = parcel.readInt32(); 396cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth = parcel.readInt32(); 397cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mHeight = parcel.readInt32(); 39801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFormat = parcel.readInt32(); 39901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mFlags = parcel.readInt32(); 40001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 40101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (clientBinder != NULL) 40201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian mClient = SurfaceComposerClient::clientForConnection(clientBinder); 40301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 40401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian init(); 40501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 40601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 40701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init() 40801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 409076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::setSwapInterval = setSwapInterval; 410076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::dequeueBuffer = dequeueBuffer; 411076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::lockBuffer = lockBuffer; 412076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_window_t::queueBuffer = queueBuffer; 413cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian android_native_window_t::query = query; 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle.makeInvalid(); 415076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian DisplayInfo dinfo; 416076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceComposerClient::getDisplayInfo(0, &dinfo); 417076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi; 418076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi; 419076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: set real values here 420076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::minSwapInterval) = 1; 421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<int&>(android_native_window_t::maxSwapInterval) = 1; 422076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const_cast<uint32_t&>(android_native_window_t::flags) = 0; 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 42501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 42640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface() 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 42840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // this is a client-side operation, the surface is destroyed, unmap 42940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // its buffers in this process. 43040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian for (int i=0 ; i<2 ; i++) { 43140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (mBuffers[i] != 0) { 43221c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian getBufferMapper().unregisterBuffer(mBuffers[i]->handle); 43340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 43440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 43540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 43640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // clear all references and trigger an IPC now, to make sure things 43740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian // happen without delay, since these resources are quite heavy. 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mClient.clear(); 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSurface.clear(); 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState::self()->flushCommands(); 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::validate(per_client_cblk_t const* cblk) const 444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 44540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (mToken<0 || mClient==0) { 44640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian LOGE("invalid token (%d, identity=%u) or client (%p)", 44740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian mToken, mIdentity, mClient.get()); 44840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return NO_INIT; 44940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian } 450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (cblk == 0) { 451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); 452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 453076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 454076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = cblk->validate(mToken); 455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) { 456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)", 457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mToken, mIdentity, err, strerror(-err)); 458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 459076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 460076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mIdentity != uint32_t(cblk->layers[mToken].identity)) { 461076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE("using an invalid surface id=%d, identity=%u should be %d", 462076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mToken, mIdentity, cblk->layers[mToken].identity); 463076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_INIT; 464076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 465076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 466076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 467076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 46801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 46901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool Surface::isSameSurface( 47001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian const sp<Surface>& lhs, const sp<Surface>& rhs) 47101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{ 47201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian if (lhs == 0 || rhs == 0) 47301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return false; 47401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); 47501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian} 47601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian 477076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 478076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 479076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval) 480076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 481076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 482076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 483076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 484076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window, 485076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t** buffer) 486076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 487076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 488076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->dequeueBuffer(buffer); 489076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 491076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window, 492076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t* buffer) 493076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->lockBuffer(buffer); 496076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 497076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 498076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window, 499076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian android_native_buffer_t* buffer) 500076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 501076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Surface* self = getSelf(window); 502076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return self->queueBuffer(buffer); 503076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 504076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 505cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(android_native_window_t* window, 506cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian int what, int* value) 507cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{ 508cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian Surface* self = getSelf(window); 509cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return self->query(what, value); 510cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 511cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 512076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 513076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5140926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer) 5150926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 5160926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian android_native_buffer_t* out; 5170926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t err = dequeueBuffer(&out); 5180926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian *buffer = SurfaceBuffer::getSelf(out); 519cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian // reset the width/height with the what we get from the buffer 520cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mWidth = uint32_t(out->width); 521cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian mHeight = uint32_t(out->height); 5220926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return err; 5230926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 5240926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 5250926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lockBuffer(const sp<SurfaceBuffer>& buffer) 5260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 5270926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return lockBuffer(buffer.get()); 5280926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 5290926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 5300926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::queueBuffer(const sp<SurfaceBuffer>& buffer) 5310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian{ 5320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian return queueBuffer(buffer.get()); 5330926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian} 5340926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 5350926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian// ---------------------------------------------------------------------------- 5360926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 537076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer) 538076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 539076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: dequeueBuffer() needs proper implementation 540076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 541076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mSurfaceLock); 542076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 543076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 544076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = validate(cblk); 545076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 546076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceID index(mToken); 549076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 550076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian int32_t backIdx = cblk->lock_layer(size_t(index), 551076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t::BLOCKING); 552076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 553076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (backIdx < 0) 554076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return status_t(backIdx); 555076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 556076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mBackbufferIndex = backIdx; 557076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* const lcblk = &(cblk->layers[index]); 558076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 559076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian volatile const surface_info_t* const back = lcblk->surface + backIdx; 560076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (back->flags & surface_info_t::eNeedNewBuffer) { 561076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian getBufferLocked(backIdx); 562076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 563076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 564076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]); 5650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mDirtyRegion.set(backBuffer->width, backBuffer->height); 566076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian *buffer = backBuffer.get(); 5670926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 570076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 571076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer) 572076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 57340b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian Mutex::Autolock _l(mSurfaceLock); 57440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 57540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 57640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian status_t err = validate(cblk); 57740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian if (err != NO_ERROR) 57840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian return err; 57940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian 580076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: lockBuffer() needs proper implementation 581076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return 0; 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 584076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer) 585076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 586076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian Mutex::Autolock _l(mSurfaceLock); 587076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 588076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 589076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = validate(cblk); 590076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err != NO_ERROR) 591076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 592076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 5930926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (mSwapRectangle.isValid()) { 5940926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mDirtyRegion.set(mSwapRectangle); 5950926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 5960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 597076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // transmit the dirty region 598076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian SurfaceID index(mToken); 599076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* const lcblk = &(cblk->layers[index]); 6000926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian _send_dirty_region(lcblk, mDirtyRegion); 601076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 602076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian uint32_t newstate = cblk->unlock_layer_and_post(size_t(index)); 603076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (!(newstate & eNextFlipPending)) 604076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mClient->signalServer(); 605076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 606076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return NO_ERROR; 607076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian} 608076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 609cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value) 610cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{ 611cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian switch (what) { 612cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian case NATIVE_WINDOW_WIDTH: 613cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian *value = int(mWidth); 614cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return NO_ERROR; 615cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian case NATIVE_WINDOW_HEIGHT: 616cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian *value = int(mHeight); 617cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return NO_ERROR; 618cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian } 619cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian return BAD_VALUE; 620cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian} 621cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian 622076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ---------------------------------------------------------------------------- 623076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) { 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return Surface::lock(info, NULL, blocking); 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6280926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 629076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 630076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: needs some locking here 6310926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6320926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian sp<SurfaceBuffer> backBuffer; 633076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = dequeueBuffer(&backBuffer); 634076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 635076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian err = lockBuffer(backBuffer); 636076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 637076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // we handle copy-back here... 638076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 639076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Rect bounds(backBuffer->width, backBuffer->height); 6400926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Region scratch(bounds); 6410926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); 642076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 643076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian per_client_cblk_t* const cblk = mClient->mControl; 644076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]); 645076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex; 646076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (back->flags & surface_info_t::eBufferDirty) { 647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // content is meaningless in this case and the whole surface 648076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // needs to be redrawn. 649076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian newDirtyRegion.set(bounds); 6500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } else { 6510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian newDirtyRegion.andSelf(bounds); 65214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]); 65314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian if (backBuffer->width == frontBuffer->width && 65414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian backBuffer->height == frontBuffer->height && 65514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian !(lcblk->flags & eNoCopyBack)) 65614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian { 6570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); 6580926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian if (!copyback.isEmpty() && frontBuffer!=0) { 6590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian // copy front to back 6600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian copyBlt(backBuffer, frontBuffer, copyback); 6610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian } 662076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 663076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 6640926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mDirtyRegion = newDirtyRegion; 6650926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mOldDirtyRegion = newDirtyRegion; 666076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 667e71212ba5397387100a578d23b15862518a7a859Mathias Agopian void* vaddr; 6680926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t res = backBuffer->lock( 6690926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 670e71212ba5397387100a578d23b15862518a7a859Mathias Agopian newDirtyRegion.bounds(), &vaddr); 6710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 672076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGW_IF(res, "failed locking buffer %d (%p)", 6730926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mBackbufferIndex, backBuffer->handle); 6740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 6750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mLockedBuffer = backBuffer; 6760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->w = backBuffer->width; 6770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->h = backBuffer->height; 6780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->s = backBuffer->stride; 6790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->usage = backBuffer->usage; 6800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian other->format = backBuffer->format; 681e71212ba5397387100a578d23b15862518a7a859Mathias Agopian other->bits = vaddr; 682076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 683076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 684076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 685edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 686076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 687076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost() 688076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 689076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // FIXME: needs some locking here 690076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian 691076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (mLockedBuffer == 0) 692076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return BAD_VALUE; 693edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 6940926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian status_t res = mLockedBuffer->unlock(); 695076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGW_IF(res, "failed unlocking buffer %d (%p)", 6960926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian mBackbufferIndex, mLockedBuffer->handle); 6970926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian 698076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = queueBuffer(mLockedBuffer); 699076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian mLockedBuffer = 0; 700076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 701edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 702edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 703076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianvoid Surface::_send_dirty_region( 704076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian layer_cblk_t* lcblk, const Region& dirty) 705076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{ 706076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift; 707076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian flat_region_t* flat_region = lcblk->region + index; 708076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = dirty.write(flat_region, sizeof(flat_region_t)); 709076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err < NO_ERROR) { 710076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian // region doesn't fit, use the bounds 711076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian const Region reg(dirty.bounds()); 712076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian reg.write(flat_region, sizeof(flat_region_t)); 713076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 714edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 715edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 716edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) { 717edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSwapRectangle = r; 718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 720076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::getBufferLocked(int index) 721edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 722076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian status_t err = NO_MEMORY; 723076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<SurfaceBuffer> buffer = mSurface->getBuffer(); 724076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL"); 725076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (buffer != 0) { 726076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian sp<SurfaceBuffer>& currentBuffer(mBuffers[index]); 727076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (currentBuffer != 0) { 72821c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian getBufferMapper().unregisterBuffer(currentBuffer->handle); 729076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian currentBuffer.clear(); 730076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian } 73121c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian err = getBufferMapper().registerBuffer(buffer->handle); 732076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); 733076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian if (err == NO_ERROR) { 734076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian currentBuffer = buffer; 735edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 736edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 737076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian return err; 738edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 739edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 740edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 741edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 742