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