VirtualDisplaySurface.cpp revision 80e0a397a4712666661ecc629a64ec26e7f6aac3
1/* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "VirtualDisplaySurface.h" 18#include "HWComposer.h" 19 20// --------------------------------------------------------------------------- 21namespace android { 22// --------------------------------------------------------------------------- 23 24VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int disp, 25 const sp<IGraphicBufferProducer>& sink, const String8& name) 26: mHwc(hwc), 27 mDisplayId(disp), 28 mSource(new BufferQueueInterposer(sink, name)), 29 mName(name), 30 mReleaseFence(Fence::NO_FENCE) 31{} 32 33VirtualDisplaySurface::~VirtualDisplaySurface() { 34 if (mAcquiredBuffer != NULL) { 35 status_t result = mSource->releaseBuffer(mReleaseFence); 36 ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": " 37 "failed to release previous buffer: %d", 38 mName.string(), result); 39 } 40} 41 42sp<IGraphicBufferProducer> VirtualDisplaySurface::getIGraphicBufferProducer() const { 43 return mSource; 44} 45 46status_t VirtualDisplaySurface::compositionComplete() { 47 return NO_ERROR; 48} 49 50status_t VirtualDisplaySurface::advanceFrame() { 51 Mutex::Autolock lock(mMutex); 52 status_t result = NO_ERROR; 53 54 if (mAcquiredBuffer != NULL) { 55 result = mSource->releaseBuffer(mReleaseFence); 56 ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": " 57 "failed to release previous buffer: %d", 58 mName.string(), result); 59 mAcquiredBuffer.clear(); 60 mReleaseFence = Fence::NO_FENCE; 61 } 62 63 sp<Fence> fence; 64 result = mSource->acquireBuffer(&mAcquiredBuffer, &fence); 65 if (result == BufferQueueInterposer::NO_BUFFER_AVAILABLE) { 66 result = mSource->pullEmptyBuffer(); 67 if (result != NO_ERROR) 68 return result; 69 result = mSource->acquireBuffer(&mAcquiredBuffer, &fence); 70 } 71 if (result != NO_ERROR) 72 return result; 73 74 return mHwc.fbPost(mDisplayId, fence, mAcquiredBuffer); 75} 76 77status_t VirtualDisplaySurface::setReleaseFenceFd(int fenceFd) { 78 if (fenceFd >= 0) { 79 sp<Fence> fence(new Fence(fenceFd)); 80 Mutex::Autolock lock(mMutex); 81 sp<Fence> mergedFence = Fence::merge( 82 String8::format("VirtualDisplaySurface \"%s\"", 83 mName.string()), 84 mReleaseFence, fence); 85 if (!mergedFence->isValid()) { 86 ALOGE("VirtualDisplaySurface \"%s\": failed to merge release fence", 87 mName.string()); 88 // synchronization is broken, the best we can do is hope fences 89 // signal in order so the new fence will act like a union 90 mReleaseFence = fence; 91 return BAD_VALUE; 92 } 93 mReleaseFence = mergedFence; 94 } 95 return NO_ERROR; 96} 97 98void VirtualDisplaySurface::dump(String8& result) const { 99} 100 101// --------------------------------------------------------------------------- 102} // namespace android 103// --------------------------------------------------------------------------- 104