VirtualDisplaySurface.cpp revision ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0a
199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall/*
299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * Copyright 2013 The Android Open Source Project
399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall *
499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * Licensed under the Apache License, Version 2.0 (the "License");
599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * you may not use this file except in compliance with the License.
699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * You may obtain a copy of the License at
799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall *
899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall *      http://www.apache.org/licenses/LICENSE-2.0
999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall *
1099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * Unless required by applicable law or agreed to in writing, software
1199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * distributed under the License is distributed on an "AS IS" BASIS,
1299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * See the License for the specific language governing permissions and
1499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall * limitations under the License.
1599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall */
1699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
1799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "VirtualDisplaySurface.h"
1880e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall#include "HWComposer.h"
1999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
2099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// ---------------------------------------------------------------------------
2199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallnamespace android {
2299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// ---------------------------------------------------------------------------
2399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
24ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse HallVirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
2599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        const sp<IGraphicBufferProducer>& sink, const String8& name)
2699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall:   mHwc(hwc),
27ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    mDisplayId(dispId),
287414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall    mName(name)
29ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall{
30ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    if (mDisplayId >= 0) {
31ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        mInterposer = new BufferQueueInterposer(sink, name);
32ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        mSourceProducer = mInterposer;
33ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    } else {
34ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        mSourceProducer = sink;
35ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    }
36ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
3799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
3899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse HallVirtualDisplaySurface::~VirtualDisplaySurface() {
3980e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    if (mAcquiredBuffer != NULL) {
40ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        status_t result = mInterposer->releaseBuffer(Fence::NO_FENCE);
4180e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall        ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": "
427414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall                "failed to release buffer: %d", mName.string(), result);
4380e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    }
4499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall}
4599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
4699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallsp<IGraphicBufferProducer> VirtualDisplaySurface::getIGraphicBufferProducer() const {
47ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    return mSourceProducer;
4899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall}
4999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
5099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallstatus_t VirtualDisplaySurface::compositionComplete() {
5199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    return NO_ERROR;
5299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall}
5399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
5499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallstatus_t VirtualDisplaySurface::advanceFrame() {
55ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    if (mInterposer == NULL)
56ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        return NO_ERROR;
57ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
5880e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    Mutex::Autolock lock(mMutex);
5980e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    status_t result = NO_ERROR;
6080e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall
6180e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    if (mAcquiredBuffer != NULL) {
627414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall        ALOGE("VirtualDisplaySurface \"%s\": "
637414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall                "advanceFrame called twice without onFrameCommitted",
647414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall                mName.string());
657414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall        return INVALID_OPERATION;
6680e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    }
6780e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall
6880e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    sp<Fence> fence;
69ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    result = mInterposer->acquireBuffer(&mAcquiredBuffer, &fence);
7080e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    if (result == BufferQueueInterposer::NO_BUFFER_AVAILABLE) {
71ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        result = mInterposer->pullEmptyBuffer();
7280e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall        if (result != NO_ERROR)
7380e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall            return result;
74ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        result = mInterposer->acquireBuffer(&mAcquiredBuffer, &fence);
7580e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    }
7680e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    if (result != NO_ERROR)
7780e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall        return result;
7880e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall
7980e0a397a4712666661ecc629a64ec26e7f6aac3Jesse Hall    return mHwc.fbPost(mDisplayId, fence, mAcquiredBuffer);
8099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall}
8199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
82851cfe834295224cd64bdd499872b95b19c4de8cJesse Hallvoid VirtualDisplaySurface::onFrameCommitted() {
83ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    if (mInterposer == NULL)
84ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        return;
85ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
867414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall    Mutex::Autolock lock(mMutex);
877414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall    if (mAcquiredBuffer != NULL) {
88851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        // fbFence signals when reads from the framebuffer are finished
89851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        // outFence signals when writes to the output buffer are finished
90851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        // It's unlikely that there will be an implementation where fbFence
91851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        // signals after outFence (in fact they'll typically be the same
92851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        // sync_pt), but just to be pedantic we merge them so the sink will
93851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        // be sure to wait until both are complete.
94851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId);
95851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
96851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        sp<Fence> fence = Fence::merge(
97851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall                String8::format("HWC done: %.21s", mName.string()),
98851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall                fbFence, outFence);
99851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall
100ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        status_t result = mInterposer->releaseBuffer(fence);
1017414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall        ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": "
1027414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall                "failed to release buffer: %d", mName.string(), result);
1037414965606f82ac2bcace5d3e2c8a4810517bf1eJesse Hall        mAcquiredBuffer.clear();
10499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    }
10599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall}
10699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
10799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hallvoid VirtualDisplaySurface::dump(String8& result) const {
10899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall}
10999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall
11099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// ---------------------------------------------------------------------------
11199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall} // namespace android
11299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall// ---------------------------------------------------------------------------
113