widget/gonk/libdisplay/FramebufferSurface.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 **
michael@0 3 ** Copyright 2012 The Android Open Source Project
michael@0 4 **
michael@0 5 ** Licensed under the Apache License Version 2.0(the "License");
michael@0 6 ** you may not use this file except in compliance with the License.
michael@0 7 ** You may obtain a copy of the License at
michael@0 8 **
michael@0 9 ** http://www.apache.org/licenses/LICENSE-2.0
michael@0 10 **
michael@0 11 ** Unless required by applicable law or agreed to in writing software
michael@0 12 ** distributed under the License is distributed on an "AS IS" BASIS
michael@0 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
michael@0 14 ** See the License for the specific language governing permissions and
michael@0 15 ** limitations under the License.
michael@0 16 */
michael@0 17
michael@0 18 #include <stdlib.h>
michael@0 19 #include <stdio.h>
michael@0 20 #include <string.h>
michael@0 21 #include <errno.h>
michael@0 22
michael@0 23 #include <cutils/log.h>
michael@0 24
michael@0 25 #include <utils/String8.h>
michael@0 26
michael@0 27 #include <ui/Rect.h>
michael@0 28
michael@0 29 #include <EGL/egl.h>
michael@0 30
michael@0 31 #include <hardware/hardware.h>
michael@0 32 #if ANDROID_VERSION == 17
michael@0 33 #include <gui/SurfaceTextureClient.h>
michael@0 34 #endif
michael@0 35 #include <ui/GraphicBuffer.h>
michael@0 36
michael@0 37 #include "FramebufferSurface.h"
michael@0 38 #include "GraphicBufferAlloc.h"
michael@0 39
michael@0 40 #ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS
michael@0 41 #define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2)
michael@0 42 #endif
michael@0 43
michael@0 44 // ----------------------------------------------------------------------------
michael@0 45 namespace android {
michael@0 46 // ----------------------------------------------------------------------------
michael@0 47
michael@0 48 /*
michael@0 49 * This implements the (main) framebuffer management. This class
michael@0 50 * was adapted from the version in SurfaceFlinger
michael@0 51 */
michael@0 52 FramebufferSurface::FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format,
michael@0 53 sp<BufferQueue>& bq) :
michael@0 54 #if ANDROID_VERSION >= 19
michael@0 55 ConsumerBase(bq, true),
michael@0 56 #else
michael@0 57 ConsumerBase(bq),
michael@0 58 #endif
michael@0 59 mDisplayType(disp),
michael@0 60 mCurrentBufferSlot(-1),
michael@0 61 mCurrentBuffer(0),
michael@0 62 lastHandle(0)
michael@0 63 {
michael@0 64 mName = "FramebufferSurface";
michael@0 65
michael@0 66 #if ANDROID_VERSION >= 19
michael@0 67 sp<IGraphicBufferConsumer> consumer = mConsumer;
michael@0 68 #else
michael@0 69 sp<BufferQueue> consumer = mBufferQueue;
michael@0 70 consumer->setSynchronousMode(true);
michael@0 71 #endif
michael@0 72 consumer->setConsumerName(mName);
michael@0 73 consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
michael@0 74 GRALLOC_USAGE_HW_RENDER |
michael@0 75 GRALLOC_USAGE_HW_COMPOSER);
michael@0 76 consumer->setDefaultBufferFormat(format);
michael@0 77 consumer->setDefaultBufferSize(width, height);
michael@0 78 consumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
michael@0 79 }
michael@0 80
michael@0 81 status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
michael@0 82 Mutex::Autolock lock(mMutex);
michael@0 83
michael@0 84 BufferQueue::BufferItem item;
michael@0 85 #if ANDROID_VERSION >= 19
michael@0 86 status_t err = acquireBufferLocked(&item, 0);
michael@0 87 #else
michael@0 88 status_t err = acquireBufferLocked(&item);
michael@0 89 #endif
michael@0 90 if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
michael@0 91 outBuffer = mCurrentBuffer;
michael@0 92 return NO_ERROR;
michael@0 93 } else if (err != NO_ERROR) {
michael@0 94 ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
michael@0 95 return err;
michael@0 96 }
michael@0 97
michael@0 98 // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
michael@0 99 // then we may have acquired the slot we already own. If we had released
michael@0 100 // our current buffer before we call acquireBuffer then that release call
michael@0 101 // would have returned STALE_BUFFER_SLOT, and we would have called
michael@0 102 // freeBufferLocked on that slot. Because the buffer slot has already
michael@0 103 // been overwritten with the new buffer all we have to do is skip the
michael@0 104 // releaseBuffer call and we should be in the same state we'd be in if we
michael@0 105 // had released the old buffer first.
michael@0 106 if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
michael@0 107 item.mBuf != mCurrentBufferSlot) {
michael@0 108 // Release the previous buffer.
michael@0 109 #if ANDROID_VERSION >= 19
michael@0 110 err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer,
michael@0 111 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
michael@0 112 #else
michael@0 113 err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY,
michael@0 114 EGL_NO_SYNC_KHR);
michael@0 115 #endif
michael@0 116 if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) {
michael@0 117 ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
michael@0 118 return err;
michael@0 119 }
michael@0 120 }
michael@0 121 mCurrentBufferSlot = item.mBuf;
michael@0 122 mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
michael@0 123 outFence = item.mFence;
michael@0 124 outBuffer = mCurrentBuffer;
michael@0 125 return NO_ERROR;
michael@0 126 }
michael@0 127
michael@0 128 // Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
michael@0 129 void FramebufferSurface::onFrameAvailable() {
michael@0 130 sp<GraphicBuffer> buf;
michael@0 131 sp<Fence> acquireFence;
michael@0 132 status_t err = nextBuffer(buf, acquireFence);
michael@0 133 if (err != NO_ERROR) {
michael@0 134 ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
michael@0 135 strerror(-err), err);
michael@0 136 return;
michael@0 137 }
michael@0 138 if (acquireFence.get() && acquireFence->isValid())
michael@0 139 mPrevFBAcquireFence = new Fence(acquireFence->dup());
michael@0 140 else
michael@0 141 mPrevFBAcquireFence = Fence::NO_FENCE;
michael@0 142
michael@0 143 lastHandle = buf->handle;
michael@0 144 }
michael@0 145
michael@0 146 void FramebufferSurface::freeBufferLocked(int slotIndex) {
michael@0 147 ConsumerBase::freeBufferLocked(slotIndex);
michael@0 148 if (slotIndex == mCurrentBufferSlot) {
michael@0 149 mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
michael@0 150 }
michael@0 151 }
michael@0 152
michael@0 153 status_t FramebufferSurface::setReleaseFenceFd(int fenceFd) {
michael@0 154 status_t err = NO_ERROR;
michael@0 155 if (fenceFd >= 0) {
michael@0 156 sp<Fence> fence(new Fence(fenceFd));
michael@0 157 if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
michael@0 158 #if ANDROID_VERSION >= 19
michael@0 159 status_t err = addReleaseFence(mCurrentBufferSlot, mCurrentBuffer, fence);
michael@0 160 #else
michael@0 161 status_t err = addReleaseFence(mCurrentBufferSlot, fence);
michael@0 162 #endif
michael@0 163 ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
michael@0 164 strerror(-err), err);
michael@0 165 }
michael@0 166 }
michael@0 167 return err;
michael@0 168 }
michael@0 169
michael@0 170 int FramebufferSurface::GetPrevFBAcquireFd() {
michael@0 171 return mPrevFBAcquireFence->dup();
michael@0 172 }
michael@0 173
michael@0 174 status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
michael@0 175 {
michael@0 176 return INVALID_OPERATION;
michael@0 177 }
michael@0 178
michael@0 179 status_t FramebufferSurface::compositionComplete()
michael@0 180 {
michael@0 181 return NO_ERROR;
michael@0 182 }
michael@0 183
michael@0 184 void FramebufferSurface::dump(String8& result) {
michael@0 185 ConsumerBase::dump(result);
michael@0 186 }
michael@0 187
michael@0 188 void FramebufferSurface::dump(String8& result, const char* prefix) {
michael@0 189 ConsumerBase::dump(result);
michael@0 190 }
michael@0 191
michael@0 192 // ----------------------------------------------------------------------------
michael@0 193 }; // namespace android
michael@0 194 // ----------------------------------------------------------------------------

mercurial