Surface.cpp revision cbb288bfe89f585bf48371bd31b2d4aafa32f32e
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "Surface"
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Errors.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h>
28cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <utils/CallStack.h>
29c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IPCThreadState.h>
30c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/DisplayInfo.h>
34076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/BufferMapper.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/ISurface.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Surface.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/SurfaceComposerClient.h>
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ui/Rect.h>
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
407189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian#include <pixelflinger/pixelflinger.h>
41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
42cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian#include <private/ui/SharedBufferStack.h>
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/ui/LayerState.h>
447189c0054e29a66d945f5657c48d5ecf538ea511Mathias Agopian#include <private/ui/SurfaceBuffer.h>
45076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------
49076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5014998596937791c8efdfd61411236a7c7f66c064Mathias Agopianstatic status_t copyBlt(
510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        const sp<SurfaceBuffer>& dst,
520926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        const sp<SurfaceBuffer>& src,
530926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        const Region& reg)
54076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
5514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    status_t err;
5614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    uint8_t const * src_bits = NULL;
5714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
5814998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    LOGE_IF(err, "error locking src buffer %s", strerror(-err));
590926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
6014998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    uint8_t* dst_bits = NULL;
6114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
6214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
6314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
6414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    Region::const_iterator head(reg.begin());
6514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    Region::const_iterator tail(reg.end());
6614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (head != tail && src_bits && dst_bits) {
67076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        // NOTE: dst and src must be the same format
68076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t bpp = bytesPerPixel(src->format);
69076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t dbpr = dst->stride * bpp;
70076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        const size_t sbpr = src->stride * bpp;
710926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
7214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        while (head != tail) {
7314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian            const Rect& r(*head++);
740926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            ssize_t h = r.height();
750926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (h <= 0) continue;
760926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            size_t size = r.width() * bpp;
770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            if (dbpr==sbpr && size==sbpr) {
800926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                size *= h;
810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                h = 1;
82076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            do {
840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                memcpy(d, s, size);
850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                d += dbpr;
860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                s += sbpr;
870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            } while (--h > 0);
88076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
89076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
9114998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (src_bits)
9214998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        src->unlock();
9314998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
9414998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    if (dst_bits)
9514998596937791c8efdfd61411236a7c7f66c064Mathias Agopian        dst->unlock();
9614998596937791c8efdfd61411236a7c7f66c064Mathias Agopian
9714998596937791c8efdfd61411236a7c7f66c064Mathias Agopian    return err;
98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
10062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
10162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian//  SurfaceControl
10262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian// ============================================================================
10362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
10401b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurfaceControl::SurfaceControl(
10501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceComposerClient>& client,
10662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const sp<ISurface>& surface,
10762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        const ISurfaceFlingerClient::surface_data_t& data,
10818d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
10962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    : mClient(client), mSurface(surface),
11062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian      mToken(data.token), mIdentity(data.identity),
1111c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian      mWidth(data.width), mHeight(data.height), mFormat(data.format),
1121c97d2ebe1f035beabd90089bfc78326b73d7864Mathias Agopian      mFlags(flags)
11362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
11462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
11518d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian
11662185b7335e85211dc4d0e2003354eb3ea2e66efMathias AgopianSurfaceControl::~SurfaceControl()
11762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
11862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
11962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
12062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
12162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::destroy()
12262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
12318d8446fe1596cd50561777e1d1a8c7b39c689f6Mathias Agopian    if (isValid()) {
12462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        mClient->destroySurface(mToken);
12562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
12662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
12762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // clear all references and trigger an IPC now, to make sure things
12862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // happen without delay, since these resources are quite heavy.
12962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mClient.clear();
13062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    mSurface.clear();
13162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    IPCThreadState::self()->flushCommands();
13262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
13362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
13462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianvoid SurfaceControl::clear()
13562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
13662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // here, the window manager tells us explicitly that we should destroy
13762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // the surface's resource. Soon after this call, it will also release
13862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // its last reference (which will call the dtor); however, it is possible
13962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // that a client living in the same process still holds references which
14062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // would delay the call to the dtor -- that is why we need this explicit
14162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    // "clear()" call.
14262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    destroy();
14362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
14462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
14501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool SurfaceControl::isSameSurface(
14601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
14701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
14801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (lhs == 0 || rhs == 0)
14901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        return false;
15001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
15101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
15201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
15362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setLayer(int32_t layer) {
15462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
15501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
15662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
15762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
15862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setLayer(mToken, layer);
15962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setPosition(int32_t x, int32_t y) {
16162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
16201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
16362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
16462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
16562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setPosition(mToken, x, y);
16662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
16762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
16862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
16901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
17062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
17162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
17262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setSize(mToken, w, h);
17362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
17462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::hide() {
17562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
17601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
17762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
17862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
17962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->hide(mToken);
18062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
18162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::show(int32_t layer) {
18262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
18301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
18462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
18562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
18662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->show(mToken, layer);
18762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
18862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::freeze() {
18962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
19001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
19162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
19262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
19362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->freeze(mToken);
19462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
19562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::unfreeze() {
19662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
19701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
19862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
19962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
20062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->unfreeze(mToken);
20162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
20362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
20401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
20562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
20662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
20762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFlags(mToken, flags, mask);
20862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
20962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
21062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
21262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
21362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
21462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setTransparentRegionHint(mToken, transparent);
21562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
21662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setAlpha(float alpha) {
21762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
21801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
21962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
22062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
22162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setAlpha(mToken, alpha);
22262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
22362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
22462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
22501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
22662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
22762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
22862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
22962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
23062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopianstatus_t SurfaceControl::setFreezeTint(uint32_t tint) {
23162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    const sp<SurfaceComposerClient>& client(mClient);
23201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (client == 0) return NO_INIT;
23362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = validate(client->mControl);
23462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err < 0) return err;
23562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return client->setFreezeTint(mToken, tint);
23662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
23762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
238cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianstatus_t SurfaceControl::validate(SharedClient const* cblk) const
23962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian{
24062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (mToken<0 || mClient==0) {
24162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("invalid token (%d, identity=%u) or client (%p)",
24262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, mClient.get());
24362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
24462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
24562185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (cblk == 0) {
24662185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
24762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
24862185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
24962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    status_t err = cblk->validate(mToken);
25062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    if (err != NO_ERROR) {
25162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
25262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian                mToken, mIdentity, err, strerror(-err));
25362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return err;
25462185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
255cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    uint32_t identity = cblk->getIdentity(mToken);
256cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mIdentity != identity) {
25762185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        LOGE("using an invalid surface id=%d, identity=%u should be %d",
258cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mToken, mIdentity, identity);
25962185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian        return NO_INIT;
26062185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    }
26162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian    return NO_ERROR;
26262185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian}
26362185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
26401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianstatus_t SurfaceControl::writeSurfaceToParcel(
26501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<SurfaceControl>& control, Parcel* parcel)
26601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
26701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t flags = 0;
26801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t format = 0;
26901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    SurfaceID token = -1;
27001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    uint32_t identity = 0;
271cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    uint32_t width = 0;
272cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    uint32_t height = 0;
27301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    sp<SurfaceComposerClient> client;
27401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    sp<ISurface> sur;
27501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (SurfaceControl::isValid(control)) {
27601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        token    = control->mToken;
27701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        identity = control->mIdentity;
27801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        client   = control->mClient;
27901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        sur      = control->mSurface;
280cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        width    = control->mWidth;
281cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian        height   = control->mHeight;
28201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        format   = control->mFormat;
28301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        flags    = control->mFlags;
28401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    }
28501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
28601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
28701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(token);
28801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(identity);
289cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    parcel->writeInt32(width);
290cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    parcel->writeInt32(height);
29101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(format);
29201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    parcel->writeInt32(flags);
29301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return NO_ERROR;
29401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
29501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
29601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopiansp<Surface> SurfaceControl::getSurface() const
29701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
29801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    Mutex::Autolock _l(mLock);
29901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (mSurfaceData == 0) {
30001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
30101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    }
30201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return mSurfaceData;
30301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
30401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
305076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
306076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian//  Surface
307076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ============================================================================
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30901b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const sp<SurfaceControl>& surface)
31001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    : mClient(surface->mClient), mSurface(surface->mSurface),
31101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian      mToken(surface->mToken), mIdentity(surface->mIdentity),
3120926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian      mFormat(surface->mFormat), mFlags(surface->mFlags),
313cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian      mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL),
314ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian      mWidth(surface->mWidth), mHeight(surface->mHeight)
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
316cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mSharedBufferClient = new SharedBufferClient(
317cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            mClient->mControl, mToken, 2);
318cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
31901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    init();
32001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
32162185b7335e85211dc4d0e2003354eb3ea2e66efMathias Agopian
32201b766839e06c32540cef100e3a7710d12cf1eefMathias AgopianSurface::Surface(const Parcel& parcel)
323cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    :  mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL)
32401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
32501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    sp<IBinder> clientBinder = parcel.readStrongBinder();
32601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
32701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mToken      = parcel.readInt32();
32801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mIdentity   = parcel.readInt32();
329cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    mWidth      = parcel.readInt32();
330cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    mHeight     = parcel.readInt32();
33101b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mFormat     = parcel.readInt32();
33201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    mFlags      = parcel.readInt32();
33301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
334cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // FIXME: what does that mean if clientBinder is NULL here?
335cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (clientBinder != NULL) {
33601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        mClient = SurfaceComposerClient::clientForConnection(clientBinder);
33701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
338cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mSharedBufferClient = new SharedBufferClient(
339cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mClient->mControl, mToken, 2);
340cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
341cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
34201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    init();
34301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
34401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
34501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianvoid Surface::init()
34601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
347076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::setSwapInterval  = setSwapInterval;
348076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::dequeueBuffer    = dequeueBuffer;
349076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::lockBuffer       = lockBuffer;
350076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    android_native_window_t::queueBuffer      = queueBuffer;
351cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    android_native_window_t::query            = query;
3525221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    android_native_window_t::perform          = perform;
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle.makeInvalid();
354076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    DisplayInfo dinfo;
355076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
356076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
357076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
358076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    // FIXME: set real values here
359076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
360076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
361076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
3625221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    // be default we request a hardware surface
3635221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    mUsage = GRALLOC_USAGE_HW_RENDER;
364ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    mUsageChanged = true;
365cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mNeedFullUpdate = false;
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias AgopianSurface::~Surface()
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
37040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // this is a client-side operation, the surface is destroyed, unmap
37140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // its buffers in this process.
37240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    for (int i=0 ; i<2 ; i++) {
37350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
37421c59d0070fe24a8e04e52ce04d511a924a9932fMathias Agopian            getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
37540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        }
37640b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
37740b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
37840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // clear all references and trigger an IPC now, to make sure things
37940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    // happen without delay, since these resources are quite heavy.
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mClient.clear();
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurface.clear();
382cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    delete mSharedBufferClient;
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    IPCThreadState::self()->flushCommands();
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
386ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopiansp<SurfaceComposerClient> Surface::getClient() const {
387ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    return mClient;
388ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
389ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
390ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopiansp<ISurface> Surface::getISurface() const {
391ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    return mSurface;
392ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
393ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
394ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianbool Surface::isValid() {
395ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    return mToken>=0 && mClient!=0;
396ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
397ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
398cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianstatus_t Surface::validate(SharedClient const* cblk) const
399076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
400ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<SurfaceComposerClient> client(getClient());
40140b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (mToken<0 || mClient==0) {
40240b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        LOGE("invalid token (%d, identity=%u) or client (%p)",
403ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian                mToken, mIdentity, client.get());
40440b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return NO_INIT;
40540b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    }
406076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (cblk == 0) {
407076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
408076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return NO_INIT;
409076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
410076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = cblk->validate(mToken);
411076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR) {
412076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
413076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                mToken, mIdentity, err, strerror(-err));
414076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
415076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
416cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    uint32_t identity = cblk->getIdentity(mToken);
417cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mIdentity != identity) {
418076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        LOGE("using an invalid surface id=%d, identity=%u should be %d",
419cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mToken, mIdentity, identity);
420076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return NO_INIT;
421076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
422076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return NO_ERROR;
423076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
424076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
42501b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
42601b766839e06c32540cef100e3a7710d12cf1eefMathias Agopianbool Surface::isSameSurface(
42701b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        const sp<Surface>& lhs, const sp<Surface>& rhs)
42801b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian{
42901b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    if (lhs == 0 || rhs == 0)
43001b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian        return false;
431ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
43201b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
43301b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian}
43401b766839e06c32540cef100e3a7710d12cf1eefMathias Agopian
435076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
436076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
437cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianint Surface::setSwapInterval(android_native_window_t* window, int interval) {
438076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return 0;
439076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
440076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
441076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_window_t* window,
442cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t** buffer) {
443076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
444076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->dequeueBuffer(buffer);
445076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
446076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
447076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_window_t* window,
448cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
449076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
450076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->lockBuffer(buffer);
451076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
452076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
453076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_window_t* window,
454cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        android_native_buffer_t* buffer) {
455076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    Surface* self = getSelf(window);
456076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return self->queueBuffer(buffer);
457076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
458076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
459cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(android_native_window_t* window,
460cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int what, int* value) {
461cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    Surface* self = getSelf(window);
462cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return self->query(what, value);
463cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
464cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
4655221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(android_native_window_t* window,
466cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        int operation, ...) {
4675221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_list args;
4685221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_start(args, operation);
4695221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    Surface* self = getSelf(window);
4705221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = self->perform(operation, args);
4715221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    va_end(args);
4725221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
4735221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
4745221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
475076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
476076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
477cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianstatus_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer) {
4780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    android_native_buffer_t* out;
4790926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    status_t err = dequeueBuffer(&out);
480ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    if (err == NO_ERROR) {
481ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian        *buffer = SurfaceBuffer::getSelf(out);
482ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    }
4830926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    return err;
4840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian}
4850926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
4860926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian// ----------------------------------------------------------------------------
4870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
488cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
489076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::dequeueBuffer(android_native_buffer_t** buffer)
490076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
491ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<SurfaceComposerClient> client(getClient());
492cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = validate(client->mControl);
493076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
494076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
495076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
496cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    ssize_t bufIdx = mSharedBufferClient->dequeue();
497cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (bufIdx < 0) {
498cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
499cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return bufIdx;
50004bc12bd4316e2928134037cd0f81c6d8b2adcc8Mathias Agopian    }
501cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
502cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // FIXME: in case of failure below, we need to undo the dequeue
503cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
504cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    uint32_t usage;
505cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    const bool usageChanged = getUsage(&usage);
506cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    const sp<SurfaceBuffer>& backBuffer(mBuffers[bufIdx]);
507cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if ((backBuffer == 0) || usageChanged ||
508cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            mSharedBufferClient->needNewBuffer(bufIdx)) {
509cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = getBufferLocked(bufIdx, usage);
510cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
511cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                bufIdx, usage, strerror(-err));
51250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (err == NO_ERROR) {
51350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            // reset the width/height with the what we get from the buffer
51450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mWidth  = uint32_t(backBuffer->width);
51550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            mHeight = uint32_t(backBuffer->height);
51650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        }
517076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
518076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
519cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    // if we still don't have a buffer here, we probably ran out of memory
520cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (!err && backBuffer==0) {
521cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = NO_MEMORY;
522cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
523cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
524cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    if (err == NO_ERROR) {
525cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mDirtyRegion.set(backBuffer->width, backBuffer->height);
526cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *buffer = backBuffer.get();
527cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } else {
528cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mSharedBufferClient->undoDequeue(bufIdx);
529cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    }
53050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
531cf81c84e43eb33931b950fa2c9b4c6f51afe7197Mathias Agopian    return err;
532076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
533076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
534076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::lockBuffer(android_native_buffer_t* buffer)
535076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
536ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<SurfaceComposerClient> client(getClient());
537cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = validate(client->mControl);
53840b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian    if (err != NO_ERROR)
53940b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian        return err;
54040b7f6e0433b89c27b2fe5a1c0c47f67b42eceb2Mathias Agopian
541cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    int32_t bufIdx = SurfaceBuffer::getSelf(buffer)->getIndex();
542cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->lock(bufIdx);
543cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
544cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
547076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianint Surface::queueBuffer(android_native_buffer_t* buffer)
548076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
549ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<SurfaceComposerClient> client(getClient());
550cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = validate(client->mControl);
551076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err != NO_ERROR)
552076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return err;
553076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
5540926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    if (mSwapRectangle.isValid()) {
5550926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian        mDirtyRegion.set(mSwapRectangle);
5560926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    }
5570926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
558cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    int32_t bufIdx = SurfaceBuffer::getSelf(buffer)->getIndex();
559cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
560cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = mSharedBufferClient->queue(bufIdx);
561cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
562076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
563cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (err == NO_ERROR) {
564cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // FIXME: can we avoid this IPC if we know there is one pending?
565ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian        client->signalServer();
566cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
567cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return err;
568076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
569076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
570cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopianint Surface::query(int what, int* value)
571cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian{
572cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    switch (what) {
573cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_WIDTH:
574cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mWidth);
575cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
576cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_HEIGHT:
577cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mHeight);
578cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
579cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    case NATIVE_WINDOW_FORMAT:
580cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        *value = int(mFormat);
581cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return NO_ERROR;
582cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    }
583cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian    return BAD_VALUE;
584cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian}
585cb6b9041647b4f080324742eee5ce709960ff610Mathias Agopian
5865221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianint Surface::perform(int operation, va_list args)
5875221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian{
5885221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    int res = NO_ERROR;
5895221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    switch (operation) {
5905221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian        case NATIVE_WINDOW_SET_USAGE:
591ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian            setUsage( va_arg(args, int) );
5925221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian            break;
5935221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian        default:
5945221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian            res = NAME_NOT_FOUND;
5955221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian            break;
5965221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    }
5975221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    return res;
5985221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian}
5995221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian
600ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopianvoid Surface::setUsage(uint32_t reqUsage)
601ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian{
602ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
603ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    if (mUsage != reqUsage) {
604ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian        mUsageChanged = true;
605ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian        mUsage = reqUsage;
606ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    }
607ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian}
608ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
609cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopianbool Surface::getUsage(uint32_t* usage)
610cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian{
611cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    Mutex::Autolock _l(mSurfaceLock);
612cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    *usage = mUsage;
613cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mUsageChanged) {
614cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        mUsageChanged = false;
615cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return true;
616cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
617cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    return false;
618cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian}
619cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
620076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian// ----------------------------------------------------------------------------
621076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t Surface::lock(SurfaceInfo* info, bool blocking) {
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return Surface::lock(info, NULL, blocking);
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
6260926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopianstatus_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
627076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
628cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mApiLock.tryLock() != NO_ERROR) {
629cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("calling Surface::lock() from different threads!");
630cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        CallStack stack;
631cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        stack.update();
632cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        stack.dump("Surface::lock called from different threads");
633cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        return WOULD_BLOCK;
634cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
635cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
6365221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopian    // we're intending to do software rendering from this point
637ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
638ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
6390926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian    sp<SurfaceBuffer> backBuffer;
640076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = dequeueBuffer(&backBuffer);
641cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
642076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (err == NO_ERROR) {
643cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        err = lockBuffer(backBuffer.get());
644cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
645cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                backBuffer->getIndex(), strerror(-err));
646076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        if (err == NO_ERROR) {
647076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            // we handle copy-back here...
648cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
649076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            const Rect bounds(backBuffer->width, backBuffer->height);
6500926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            Region scratch(bounds);
6510926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
652076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
653cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            if (mNeedFullUpdate) {
654cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                // reset newDirtyRegion to bounds when a buffer is reallocated
655cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                // it would be better if this information was associated with
656cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                // the buffer and made available to outside of Surface.
657cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                // This will do for now though.
658cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mNeedFullUpdate = false;
659076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                newDirtyRegion.set(bounds);
6600926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            } else {
6610926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                newDirtyRegion.andSelf(bounds);
662cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            }
663cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
664cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            const sp<SurfaceBuffer>& frontBuffer(mPostedBuffer);
665cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            if (frontBuffer !=0 &&
666cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                backBuffer->width  == frontBuffer->width &&
667cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                backBuffer->height == frontBuffer->height &&
668cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                !(mFlags & ISurfaceComposer::eDestroyBackbuffer))
669cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            {
670cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
671cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                if (!copyback.isEmpty() && frontBuffer!=0) {
672cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    // copy front to back
673cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    copyBlt(backBuffer, frontBuffer, copyback);
674076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                }
675076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian            }
676cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
6770926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mDirtyRegion = newDirtyRegion;
6780926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mOldDirtyRegion = newDirtyRegion;
679076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
680e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            void* vaddr;
6810926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            status_t res = backBuffer->lock(
6820926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
683e71212ba5397387100a578d23b15862518a7a859Mathias Agopian                    newDirtyRegion.bounds(), &vaddr);
6840926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
685cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            LOGW_IF(res, "failed locking buffer (handle = %p)",
686cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                    backBuffer->handle);
6870926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
6880926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            mLockedBuffer = backBuffer;
6890926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->w      = backBuffer->width;
6900926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->h      = backBuffer->height;
6910926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->s      = backBuffer->stride;
6920926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->usage  = backBuffer->usage;
6930926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian            other->format = backBuffer->format;
694e71212ba5397387100a578d23b15862518a7a859Mathias Agopian            other->bits   = vaddr;
695076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        }
696076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
697cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mApiLock.unlock();
698076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
699edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
700076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
701076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopianstatus_t Surface::unlockAndPost()
702076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian{
703cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (mLockedBuffer == 0) {
704cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("unlockAndPost failed, no locked buffer");
705076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        return BAD_VALUE;
706cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
707edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
708cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    status_t err = mLockedBuffer->unlock();
709cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
7100926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian
711cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    err = queueBuffer(mLockedBuffer.get());
712cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
713cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            mLockedBuffer->getIndex(), strerror(-err));
714cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian
715cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    mPostedBuffer = mLockedBuffer;
716076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mLockedBuffer = 0;
717076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
718edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
719edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
720edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid Surface::setSwapRectangle(const Rect& r) {
721ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    Mutex::Autolock _l(mSurfaceLock);
722edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSwapRectangle = r;
723edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
724edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
7255221271375f361b84a6eeec3d7086f223997fbb3Mathias Agopianstatus_t Surface::getBufferLocked(int index, int usage)
726edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
727ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    sp<ISurface> s(mSurface);
728ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian    if (s == 0) return NO_INIT;
729ba5972ffdc7179dd9a387f22032eb18666d97917Mathias Agopian
730076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    status_t err = NO_MEMORY;
73150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
73250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    // free the current buffer
73350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
73450517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    if (currentBuffer != 0) {
73550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        getBufferMapper().unregisterBuffer(currentBuffer->handle);
73650517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        currentBuffer.clear();
73750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    }
73850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian
739cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    sp<SurfaceBuffer> buffer = s->requestBuffer(index, usage);
740cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    LOGE_IF(buffer==0,
741cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            "ISurface::getBuffer(%d, %08x) returned NULL",
742cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            index, usage);
74350517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian    if (buffer != 0) { // this should never happen by construction
744cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE_IF(buffer->handle == NULL,
745cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                "requestBuffer(%d, %08x) returned a buffer with a null handle",
746cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                index, usage);
74750517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian        if (buffer->handle != NULL) {
74850517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            err = getBufferMapper().registerBuffer(buffer->handle);
74950517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
75050517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian                    err, strerror(-err));
75150517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            if (err == NO_ERROR) {
75250517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian                currentBuffer = buffer;
753cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                currentBuffer->setIndex(index);
754cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian                mNeedFullUpdate = true;
75550517543d84446fc91fa65c60eda6d2e2724de10Mathias Agopian            }
756edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
757edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
758076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return err;
759edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
760edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
761edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
762edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
763