Surface.cpp revision 1681d95989271f3a9ac0dbb93d10e4a29f2b4444
182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON/*
282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * Copyright (C) 2010 The Android Open Source Project
382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON *
482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * Licensed under the Apache License, Version 2.0 (the "License");
582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * you may not use this file except in compliance with the License.
682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * You may obtain a copy of the License at
782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON *
882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON *      http://www.apache.org/licenses/LICENSE-2.0
982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON *
1082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * Unless required by applicable law or agreed to in writing, software
1182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * distributed under the License is distributed on an "AS IS" BASIS,
1282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * See the License for the specific language governing permissions and
1482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON * limitations under the License.
1582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON */
1682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
1782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define LOG_TAG "Surface"
1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define ATRACE_TAG ATRACE_TAG_GRAPHICS
1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON//#define LOG_NDEBUG 0
2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <android/native_window.h>
2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <binder/Parcel.h>
2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <utils/Log.h>
2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <utils/Trace.h>
2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <ui/Fence.h>
2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <gui/IProducerListener.h>
3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <gui/ISurfaceComposer.h>
3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <gui/SurfaceComposerClient.h>
3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <gui/GLConsumer.h>
3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <gui/Surface.h>
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <private/gui/ComposerService.h>
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONnamespace android {
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONSurface::Surface(
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const sp<IGraphicBufferProducer>& bufferProducer,
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bool controlledByApp)
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    : mGraphicBufferProducer(bufferProducer)
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Initialize the ANativeWindow function pointers.
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::queueBuffer      = hook_queueBuffer;
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::query            = hook_query;
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::perform          = hook_perform;
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqWidth = 0;
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqHeight = 0;
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqFormat = 0;
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqUsage = 0;
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCrop.clear();
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTransform = 0;
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mStickyTransform = 0;
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDefaultWidth = 0;
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mDefaultHeight = 0;
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mUserWidth = 0;
7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mUserHeight = 0;
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTransformHint = 0;
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConsumerRunningBehind = false;
7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConnectedToCpu = false;
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mProducerControlledByApp = controlledByApp;
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSwapIntervalZero = false;
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONSurface::~Surface() {
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConnectedToCpu) {
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        Surface::disconnect(NATIVE_WINDOW_API_CPU);
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONsp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return mGraphicBufferProducer;
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid Surface::setSidebandStream(const sp<NativeHandle>& stream) {
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mGraphicBufferProducer->setSidebandStream(stream);
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid Surface::allocateBuffers() {
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mGraphicBufferProducer->allocateBuffers(mSwapIntervalZero, mReqWidth,
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mReqHeight, mReqFormat, mReqUsage);
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->setSwapInterval(interval);
10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_dequeueBuffer(ANativeWindow* window,
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer** buffer, int* fenceFd) {
10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->dequeueBuffer(buffer, fenceFd);
11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_cancelBuffer(ANativeWindow* window,
11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer* buffer, int fenceFd) {
11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->cancelBuffer(buffer, fenceFd);
11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_queueBuffer(ANativeWindow* window,
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer* buffer, int fenceFd) {
12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->queueBuffer(buffer, fenceFd);
12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer** buffer) {
12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindowBuffer* buf;
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int fenceFd = -1;
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int result = c->dequeueBuffer(&buf, &fenceFd);
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    sp<Fence> fence(new Fence(fenceFd));
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (waitResult != OK) {
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                waitResult);
13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        c->cancelBuffer(buf, -1);
13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return waitResult;
13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    *buffer = buf;
14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return result;
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer* buffer) {
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->cancelBuffer(buffer, -1);
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer* buffer) {
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->lockBuffer_DEPRECATED(buffer);
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindowBuffer* buffer) {
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->queueBuffer(buffer, -1);
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_query(const ANativeWindow* window,
16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                int what, int* value) {
16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    const Surface* c = getSelf(window);
16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->query(what, value);
16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::hook_perform(ANativeWindow* window, int operation, ...) {
16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    va_list args;
16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    va_start(args, operation);
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Surface* c = getSelf(window);
17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return c->perform(operation, args);
17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setSwapInterval(int interval) {
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // EGL specification states:
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //  interval is silently clamped to minimum and maximum implementation
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //  dependent values before being stored.
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (interval < minSwapInterval)
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        interval = minSwapInterval;
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (interval > maxSwapInterval)
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        interval = maxSwapInterval;
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSwapIntervalZero = (interval == 0);
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::dequeueBuffer");
19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int reqW;
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int reqH;
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool swapIntervalZero;
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t reqFormat;
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t reqUsage;
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    {
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        Mutex::Autolock lock(mMutex);
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        reqW = mReqWidth ? mReqWidth : mUserWidth;
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        reqH = mReqHeight ? mReqHeight : mUserHeight;
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        swapIntervalZero = mSwapIntervalZero;
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        reqFormat = mReqFormat;
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        reqUsage = mReqUsage;
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int buf = -1;
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    sp<Fence> fence;
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            reqW, reqH, reqFormat, reqUsage);
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (result < 0) {
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d, %d)"
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON             "failed: %d", swapIntervalZero, reqW, reqH, reqFormat, reqUsage,
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON             result);
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return result;
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // this should never happen
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        freeAllBuffers();
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (result != NO_ERROR) {
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return result;
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (fence->isValid()) {
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        *fenceFd = fence->dup();
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (*fenceFd == -1) {
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ALOGE("dequeueBuffer: error duping fence: %d", errno);
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // dup() should never fail; something is badly wrong. Soldier on
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // and hope for the best; the worst that should happen is some
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // visible corruption that lasts until the next frame.
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        *fenceFd = -1;
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    *buffer = gbuf.get();
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return OK;
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::cancelBuffer(android_native_buffer_t* buffer,
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int fenceFd) {
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::cancelBuffer");
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int i = getSlotFromBufferLocked(buffer);
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (i < 0) {
26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return i;
26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mGraphicBufferProducer->cancelBuffer(i, fence);
27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return OK;
27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::getSlotFromBufferLocked(
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        android_native_buffer_t* buffer) const {
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool dumpedState = false;
27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mSlots[i].buffer != NULL &&
27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSlots[i].buffer->handle == buffer->handle) {
27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return i;
28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return BAD_VALUE;
28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::lockBuffer");
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return OK;
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::queueBuffer");
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int64_t timestamp;
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool isAutoTimestamp = false;
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        isAutoTimestamp = true;
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            timestamp / 1000000.f);
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        timestamp = mTimestamp;
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int i = getSlotFromBufferLocked(buffer);
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (i < 0) {
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return i;
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Make sure the crop rectangle is entirely inside the buffer.
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Rect crop;
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    IGraphicBufferProducer::QueueBufferOutput output;
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero,
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            fence, mStickyTransform);
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (err != OK)  {
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t numPendingBuffers = 0;
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t hint = 0;
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &numPendingBuffers);
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // Disable transform hint if sticky transform is set.
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mStickyTransform == 0) {
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mTransformHint = hint;
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mConsumerRunningBehind = (numPendingBuffers >= 2);
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::query(int what, int* value) const {
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::query");
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    { // scope for the lock
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        Mutex::Autolock lock(mMutex);
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        switch (what) {
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_FORMAT:
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mReqFormat) {
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    *value = mReqFormat;
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    return NO_ERROR;
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sp<ISurfaceComposer> composer(
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        ComposerService::getComposerService());
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    *value = 1;
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else {
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    *value = 0;
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return NO_ERROR;
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_CONCRETE_TYPE:
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                *value = NATIVE_WINDOW_SURFACE;
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return NO_ERROR;
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_DEFAULT_WIDTH:
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                *value = mUserWidth ? mUserWidth : mDefaultWidth;
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return NO_ERROR;
36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_DEFAULT_HEIGHT:
36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                *value = mUserHeight ? mUserHeight : mDefaultHeight;
37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return NO_ERROR;
37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_TRANSFORM_HINT:
37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                *value = mTransformHint;
37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return NO_ERROR;
37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                status_t err = NO_ERROR;
37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (!mConsumerRunningBehind) {
37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    *value = 0;
37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else {
37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    err = mGraphicBufferProducer->query(what, value);
38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (err == NO_ERROR) {
38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        mConsumerRunningBehind = *value;
38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return err;
38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return mGraphicBufferProducer->query(what, value);
38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::perform(int operation, va_list args)
39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int res = NO_ERROR;
39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (operation) {
39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_CONNECT:
39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // deprecated. must return NO_ERROR.
39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_DISCONNECT:
39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // deprecated. must return NO_ERROR.
40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_USAGE:
40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetUsage(args);
40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_CROP:
40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetCrop(args);
40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFER_COUNT:
40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBufferCount(args);
40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersGeometry(args);
41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersTransform(args);
41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersStickyTransform(args);
41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersTimestamp(args);
42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersDimensions(args);
42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersUserDimensions(args);
42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetBuffersFormat(args);
43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_LOCK:
43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchLock(args);
43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_UNLOCK_AND_POST:
43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchUnlockAndPost(args);
43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_SET_SCALING_MODE:
43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchSetScalingMode(args);
43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_API_CONNECT:
44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchConnect(args);
44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    case NATIVE_WINDOW_API_DISCONNECT:
44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = dispatchDisconnect(args);
44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    default:
44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        res = NAME_NOT_FOUND;
44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        break;
44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return res;
45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchConnect(va_list args) {
45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int api = va_arg(args, int);
45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return connect(api);
45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchDisconnect(va_list args) {
45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int api = va_arg(args, int);
46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return disconnect(api);
46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetUsage(va_list args) {
46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int usage = va_arg(args, int);
46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setUsage(usage);
46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetCrop(va_list args) {
46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setCrop(reinterpret_cast<Rect const*>(rect));
47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBufferCount(va_list args) {
47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    size_t bufferCount = va_arg(args, size_t);
47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBufferCount(bufferCount);
47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBuffersGeometry(va_list args) {
47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int w = va_arg(args, int);
48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int h = va_arg(args, int);
48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int f = va_arg(args, int);
48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int err = setBuffersDimensions(w, h);
48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (err != 0) {
48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return err;
48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBuffersFormat(f);
48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBuffersDimensions(va_list args) {
49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int w = va_arg(args, int);
49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int h = va_arg(args, int);
49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBuffersDimensions(w, h);
49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBuffersUserDimensions(va_list args) {
49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int w = va_arg(args, int);
49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int h = va_arg(args, int);
49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBuffersUserDimensions(w, h);
49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBuffersFormat(va_list args) {
50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int f = va_arg(args, int);
50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBuffersFormat(f);
50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetScalingMode(va_list args) {
50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int m = va_arg(args, int);
50882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setScalingMode(m);
50982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
51082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
51182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBuffersTransform(va_list args) {
51282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int transform = va_arg(args, int);
51382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBuffersTransform(transform);
51482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
51582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
51682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchSetBuffersStickyTransform(va_list args) {
51782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int transform = va_arg(args, int);
51882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return setBuffersStickyTransform(transform);
51982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
5204ed41ba5c78e10aec0b96206709082c83d47af99ywan
5214ed41ba5c78e10aec0b96206709082c83d47af99ywanint Surface::dispatchSetBuffersTimestamp(va_list args) {
5224ed41ba5c78e10aec0b96206709082c83d47af99ywan    int64_t timestamp = va_arg(args, int64_t);
5234ed41ba5c78e10aec0b96206709082c83d47af99ywan    return setBuffersTimestamp(timestamp);
5244ed41ba5c78e10aec0b96206709082c83d47af99ywan}
5254ed41ba5c78e10aec0b96206709082c83d47af99ywan
5264ed41ba5c78e10aec0b96206709082c83d47af99ywanint Surface::dispatchLock(va_list args) {
52782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
52882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ARect* inOutDirtyBounds = va_arg(args, ARect*);
52982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return lock(outBuffer, inOutDirtyBounds);
53082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
53182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
53382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return unlockAndPost();
53482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
53582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::connect(int api) {
53882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
53982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::connect");
54082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    static sp<IProducerListener> listener = new DummyProducerListener();
54182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
54282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    IGraphicBufferProducer::QueueBufferOutput output;
54382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
54482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (err == NO_ERROR) {
54582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint32_t numPendingBuffers = 0;
54682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        uint32_t hint = 0;
54782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
54882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &numPendingBuffers);
54982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
55082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Disable transform hint if sticky transform is set.
55182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mStickyTransform == 0) {
55282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mTransformHint = hint;
55382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
55482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
55582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mConsumerRunningBehind = (numPendingBuffers >= 2);
55682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
55782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!err && api == NATIVE_WINDOW_API_CPU) {
55882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mConnectedToCpu = true;
55982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
56082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
56182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
56282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
56382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
56482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::disconnect(int api) {
56582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
56682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::disconnect");
56782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
56882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    freeAllBuffers();
56982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int err = mGraphicBufferProducer->disconnect(api);
57082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!err) {
57182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mReqFormat = 0;
57282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mReqWidth = 0;
57382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mReqHeight = 0;
57482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mReqUsage = 0;
57582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mCrop.clear();
57682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
57782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mTransform = 0;
57882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mStickyTransform = 0;
57982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (api == NATIVE_WINDOW_API_CPU) {
58182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mConnectedToCpu = false;
58282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
58382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
58482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
58582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
58682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setUsage(uint32_t reqUsage)
58882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
58982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setUsage");
59082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
59182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqUsage = reqUsage;
59282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return OK;
59382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
59482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setCrop(Rect const* rect)
59682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
59782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
59882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Rect realRect;
60082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (rect == NULL || rect->isEmpty()) {
60182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        realRect.clear();
60282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
60382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        realRect = *rect;
60482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
60582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setCrop rect=[%d %d %d %d]",
60782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            realRect.left, realRect.top, realRect.right, realRect.bottom);
60882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
61082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCrop = realRect;
61182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
61282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
61382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
61482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBufferCount(int bufferCount)
61582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
61682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
61782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBufferCount");
61882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
61982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status_t err = mGraphicBufferProducer->setBufferCount(bufferCount);
62182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
62282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            bufferCount, strerror(-err));
62382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (err == NO_ERROR) {
62582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        freeAllBuffers();
62682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
62782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
62982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
63082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBuffersDimensions(int w, int h)
63282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
63382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
63482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBuffersDimensions");
63582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (w<0 || h<0)
63782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return BAD_VALUE;
63882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((w && !h) || (!w && h))
64082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return BAD_VALUE;
64182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
64382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqWidth = w;
64482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqHeight = h;
64582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
64682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
64782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBuffersUserDimensions(int w, int h)
64982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
65082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
65182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBuffersUserDimensions");
65282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (w<0 || h<0)
65482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return BAD_VALUE;
65582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((w && !h) || (!w && h))
65782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return BAD_VALUE;
65882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
66082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mUserWidth = w;
66182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mUserHeight = h;
66282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
66382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
66482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
66582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBuffersFormat(int format)
66682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
66782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBuffersFormat");
66882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
66982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (format<0)
67082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return BAD_VALUE;
67182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
67382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mReqFormat = format;
67482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
67582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
67682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setScalingMode(int mode)
67882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
67982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
68082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setScalingMode(%d)", mode);
68182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
68282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (mode) {
68382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
68482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
68582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
68682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
68782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        default:
68882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ALOGE("unknown scaling mode: %d", mode);
68982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return BAD_VALUE;
69082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
69182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
69282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
69382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mScalingMode = mode;
69482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
69582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
69682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
69782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBuffersTransform(int transform)
69882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
69982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
70082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBuffersTransform");
70182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
70282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTransform = transform;
70382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
70482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
70582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
70682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBuffersStickyTransform(int transform)
70782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
70882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ATRACE_CALL();
70982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBuffersStickyTransform");
71082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
71182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mStickyTransform = transform;
71282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
71382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
71482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
71582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint Surface::setBuffersTimestamp(int64_t timestamp)
71682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
71782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGV("Surface::setBuffersTimestamp");
71882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Mutex::Autolock lock(mMutex);
71982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mTimestamp = timestamp;
72082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NO_ERROR;
72182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
72282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
72382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid Surface::freeAllBuffers() {
72482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
72582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSlots[i].buffer = 0;
72682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
72782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
72882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
72982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// ----------------------------------------------------------------------
73082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// the lock/unlock APIs must be used from the same thread
73182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
73282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONstatic status_t copyBlt(
73382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const sp<GraphicBuffer>& dst,
73482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const sp<GraphicBuffer>& src,
73582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const Region& reg)
73682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
73782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // src and dst with, height and format must be identical. no verification
73882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // is done here.
73982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status_t err;
74082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t const * src_bits = NULL;
74182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
74282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
74382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
74482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t* dst_bits = NULL;
74582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
74682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
74782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
74882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Region::const_iterator head(reg.begin());
74982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Region::const_iterator tail(reg.end());
75082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (head != tail && src_bits && dst_bits) {
75182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const size_t bpp = bytesPerPixel(src->format);
75282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const size_t dbpr = dst->stride * bpp;
75382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const size_t sbpr = src->stride * bpp;
75482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
75582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        while (head != tail) {
75682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            const Rect& r(*head++);
75782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ssize_t h = r.height();
75882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (h <= 0) continue;
75982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            size_t size = r.width() * bpp;
76082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
76182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
76282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (dbpr==sbpr && size==sbpr) {
76382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                size *= h;
76482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                h = 1;
76582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
76682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            do {
76782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                memcpy(d, s, size);
76882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                d += dbpr;
76982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                s += sbpr;
77082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } while (--h > 0);
77182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
77282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
77382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
77482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (src_bits)
77582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        src->unlock();
77682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
77782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (dst_bits)
77882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dst->unlock();
77982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
78182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
78282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// ----------------------------------------------------------------------------
78482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONstatus_t Surface::lock(
78682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
78782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
78882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLockedBuffer != 0) {
78982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGE("Surface::lock failed, already locked");
79082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return INVALID_OPERATION;
79182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
79282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
79382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mConnectedToCpu) {
79482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int err = Surface::connect(NATIVE_WINDOW_API_CPU);
79582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (err) {
79682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return err;
79782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
79882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // we're intending to do software rendering from this point
79982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
80082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
80182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
80282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ANativeWindowBuffer* out;
80382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int fenceFd = -1;
80482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status_t err = dequeueBuffer(&out, &fenceFd);
80582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
80682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (err == NO_ERROR) {
80782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
80882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const Rect bounds(backBuffer->width, backBuffer->height);
80982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        Region newDirtyRegion;
81182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (inOutDirtyBounds) {
81282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
81382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            newDirtyRegion.andSelf(bounds);
81482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
81582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            newDirtyRegion.set(bounds);
81682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
81782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // figure out if we can copy the frontbuffer back
81982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
82082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        const bool canCopyBack = (frontBuffer != 0 &&
82182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                backBuffer->width  == frontBuffer->width &&
82282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                backBuffer->height == frontBuffer->height &&
82382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                backBuffer->format == frontBuffer->format);
82482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
82582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (canCopyBack) {
82682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // copy the area that is invalid and not repainted this round
82782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
82882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (!copyback.isEmpty())
82982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                copyBlt(backBuffer, frontBuffer, copyback);
83082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
83182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // if we can't copy-back anything, modify the user's dirty
83282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // region to make sure they redraw the whole buffer
83382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            newDirtyRegion.set(bounds);
83482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mDirtyRegion.clear();
83582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            Mutex::Autolock lock(mMutex);
83682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
83782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSlots[i].dirtyRegion.clear();
83882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
83982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
84082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
84182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
84282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        { // scope for the lock
84382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            Mutex::Autolock lock(mMutex);
84482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
84582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (backBufferSlot >= 0) {
84682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
84782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mDirtyRegion.subtract(dirtyRegion);
84882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                dirtyRegion = newDirtyRegion;
84982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
85082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
85182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDirtyRegion.orSelf(newDirtyRegion);
85382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (inOutDirtyBounds) {
85482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            *inOutDirtyBounds = newDirtyRegion.getBounds();
85582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
85682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
85782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        void* vaddr;
85882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status_t res = backBuffer->lockAsync(
85982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
86082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                newDirtyRegion.bounds(), &vaddr, fenceFd);
86182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
86282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGW_IF(res, "failed locking buffer (handle = %p)",
86382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                backBuffer->handle);
86482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
86582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (res != 0) {
86682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            err = INVALID_OPERATION;
86782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
86882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mLockedBuffer = backBuffer;
86982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outBuffer->width  = backBuffer->width;
87082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outBuffer->height = backBuffer->height;
87182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outBuffer->stride = backBuffer->stride;
87282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outBuffer->format = backBuffer->format;
87382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            outBuffer->bits   = vaddr;
87482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
87582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
87682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
87782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
87882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
87982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONstatus_t Surface::unlockAndPost()
88082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
88182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mLockedBuffer == 0) {
88282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ALOGE("Surface::unlockAndPost failed, no locked buffer");
88382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return INVALID_OPERATION;
88482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
88582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
88682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int fd = -1;
88782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status_t err = mLockedBuffer->unlockAsync(&fd);
88882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
88982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    err = queueBuffer(mLockedBuffer.get(), fd);
89182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
89282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mLockedBuffer->handle, strerror(-err));
89382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mPostedBuffer = mLockedBuffer;
89582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLockedBuffer = 0;
89682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return err;
89782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
89882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}; // namespace android
90082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON