blob: 29e07663836f115f305977f893295c9715aed61d [file] [log] [blame]
Mathias Agopian3e876012012-06-07 17:52:54 -07001/*
2 **
Jamie Gennis1a4d8832012-08-02 20:11:05 -07003 ** Copyright 2012 The Android Open Source Project
Mathias Agopian3e876012012-06-07 17:52:54 -07004 **
5 ** Licensed under the Apache License Version 2.0(the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing software
12 ** distributed under the License is distributed on an "AS IS" BASIS
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
Dan Stoza9e56aa02015-11-02 13:00:03 -080018// #define LOG_NDEBUG 0
19#undef LOG_TAG
20#define LOG_TAG "FramebufferSurface"
21
Mathias Agopian3e876012012-06-07 17:52:54 -070022#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <errno.h>
26
27#include <cutils/log.h>
28
29#include <utils/String8.h>
30
31#include <ui/Rect.h>
32
33#include <EGL/egl.h>
34
35#include <hardware/hardware.h>
Dan Stoza84493cd2015-03-12 15:12:44 -070036#include <gui/BufferItem.h>
Jamie Gennis392edd82012-11-29 23:26:29 -080037#include <gui/GraphicBufferAlloc.h>
Dan Stoza84493cd2015-03-12 15:12:44 -070038#include <gui/Surface.h>
Mathias Agopian3e876012012-06-07 17:52:54 -070039#include <ui/GraphicBuffer.h>
40
Mathias Agopian33ceeb32013-04-01 16:54:58 -070041#include "FramebufferSurface.h"
42#include "HWComposer.h"
Mathias Agopian3e876012012-06-07 17:52:54 -070043
Jamie Genniscdbaecb2012-10-12 14:18:10 -070044#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS
45#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2)
46#endif
47
Mathias Agopian3e876012012-06-07 17:52:54 -070048// ----------------------------------------------------------------------------
49namespace android {
50// ----------------------------------------------------------------------------
51
Mathias Agopian3e876012012-06-07 17:52:54 -070052/*
53 * This implements the (main) framebuffer management. This class is used
54 * mostly by SurfaceFlinger, but also by command line GL application.
55 *
56 */
57
Mathias Agopiandb89edc2013-08-02 01:40:18 -070058FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,
59 const sp<IGraphicBufferConsumer>& consumer) :
60 ConsumerBase(consumer),
Mathias Agopianf5a33922012-09-19 18:16:22 -070061 mDisplayType(disp),
Jamie Gennis1a4d8832012-08-02 20:11:05 -070062 mCurrentBufferSlot(-1),
Dan Stoza9e56aa02015-11-02 13:00:03 -080063#ifdef USE_HWC2
64 mCurrentBuffer(),
65 mCurrentFence(Fence::NO_FENCE),
66 mHwc(hwc),
67 mHasPendingRelease(false),
68 mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
69 mPreviousBuffer()
70#else
Andy McFaddenb0d1dd32012-09-10 14:08:09 -070071 mCurrentBuffer(0),
72 mHwc(hwc)
Dan Stoza9e56aa02015-11-02 13:00:03 -080073#endif
Mathias Agopian3e876012012-06-07 17:52:54 -070074{
Dan Stoza9e56aa02015-11-02 13:00:03 -080075#ifdef USE_HWC2
76 ALOGV("Creating for display %d", disp);
77#endif
78
Andy McFaddenb0d1dd32012-09-10 14:08:09 -070079 mName = "FramebufferSurface";
Mathias Agopiandb89edc2013-08-02 01:40:18 -070080 mConsumer->setConsumerName(mName);
81 mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
Mathias Agopianf5a33922012-09-19 18:16:22 -070082 GRALLOC_USAGE_HW_RENDER |
83 GRALLOC_USAGE_HW_COMPOSER);
Dan Stoza9e56aa02015-11-02 13:00:03 -080084#ifdef USE_HWC2
85 const auto& activeConfig = mHwc.getActiveConfig(disp);
86 mConsumer->setDefaultBufferSize(activeConfig->getWidth(),
87 activeConfig->getHeight());
88#else
Mathias Agopiandb89edc2013-08-02 01:40:18 -070089 mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
Dan Stoza9e56aa02015-11-02 13:00:03 -080090 mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
91#endif
Pablo Ceballos19e3e062015-08-19 16:16:06 -070092 mConsumer->setMaxAcquiredBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS - 1);
Jesse Hall99c7dbb2013-03-14 14:29:29 -070093}
94
Jesse Hall7cd85972014-08-07 22:48:06 -070095status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) {
Jesse Hall028dc8f2013-08-20 16:35:32 -070096 return NO_ERROR;
97}
98
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -070099status_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) {
Jesse Hall38efe862013-04-06 23:12:29 -0700100 return NO_ERROR;
101}
102
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700103status_t FramebufferSurface::advanceFrame() {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800104#ifdef USE_HWC2
105 sp<GraphicBuffer> buf;
106 sp<Fence> acquireFence(Fence::NO_FENCE);
107 android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
108 status_t result = nextBuffer(buf, acquireFence, dataspace);
109 if (result != NO_ERROR) {
110 ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
111 strerror(-result), result);
112 return result;
113 }
114 result = mHwc.setClientTarget(mDisplayType, acquireFence, buf, dataspace);
115 if (result != NO_ERROR) {
116 ALOGE("error posting framebuffer: %d", result);
117 }
118 return result;
119#else
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700120 // Once we remove FB HAL support, we can call nextBuffer() from here
121 // instead of using onFrameAvailable(). No real benefit, except it'll be
122 // more like VirtualDisplaySurface.
123 return NO_ERROR;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800124#endif
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700125}
126
Dan Stoza9e56aa02015-11-02 13:00:03 -0800127#ifdef USE_HWC2
128status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer,
129 sp<Fence>& outFence, android_dataspace_t& outDataspace) {
130#else
Mathias Agopianda27af92012-09-13 18:17:13 -0700131status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800132#endif
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700133 Mutex::Autolock lock(mMutex);
Mathias Agopian3e876012012-06-07 17:52:54 -0700134
Dan Stoza84493cd2015-03-12 15:12:44 -0700135 BufferItem item;
Andy McFadden1585c4d2013-06-28 13:52:40 -0700136 status_t err = acquireBufferLocked(&item, 0);
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700137 if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
Mathias Agopianda27af92012-09-13 18:17:13 -0700138 outBuffer = mCurrentBuffer;
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700139 return NO_ERROR;
140 } else if (err != NO_ERROR) {
141 ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
142 return err;
143 }
144
145 // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
146 // then we may have acquired the slot we already own. If we had released
147 // our current buffer before we call acquireBuffer then that release call
148 // would have returned STALE_BUFFER_SLOT, and we would have called
149 // freeBufferLocked on that slot. Because the buffer slot has already
150 // been overwritten with the new buffer all we have to do is skip the
151 // releaseBuffer call and we should be in the same state we'd be in if we
152 // had released the old buffer first.
153 if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
Pablo Ceballos47650f42015-08-04 16:38:17 -0700154 item.mSlot != mCurrentBufferSlot) {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800155#ifdef USE_HWC2
156 mHasPendingRelease = true;
157 mPreviousBufferSlot = mCurrentBufferSlot;
158 mPreviousBuffer = mCurrentBuffer;
159#else
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700160 // Release the previous buffer.
Lajos Molnarc5d7b7d2013-05-03 14:50:50 -0700161 err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer,
162 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
Mathias Agopianad678e12013-07-23 17:28:53 -0700163 if (err < NO_ERROR) {
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700164 ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
165 return err;
166 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800167#endif
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700168 }
Pablo Ceballos47650f42015-08-04 16:38:17 -0700169 mCurrentBufferSlot = item.mSlot;
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700170 mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800171#ifdef USE_HWC2
172 mCurrentFence = item.mFence;
173#endif
174
Mathias Agopianda27af92012-09-13 18:17:13 -0700175 outFence = item.mFence;
176 outBuffer = mCurrentBuffer;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800177#ifdef USE_HWC2
178 outDataspace = item.mDataSpace;
179#endif
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700180 return NO_ERROR;
Mathias Agopian3e876012012-06-07 17:52:54 -0700181}
182
Dan Stoza9e56aa02015-11-02 13:00:03 -0800183#ifndef USE_HWC2
Andy McFaddenb0d1dd32012-09-10 14:08:09 -0700184// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
Dan Stoza8dc55392014-11-04 11:37:46 -0800185void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700186 sp<GraphicBuffer> buf;
Mathias Agopianda27af92012-09-13 18:17:13 -0700187 sp<Fence> acquireFence;
188 status_t err = nextBuffer(buf, acquireFence);
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700189 if (err != NO_ERROR) {
Mathias Agopianda27af92012-09-13 18:17:13 -0700190 ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700191 strerror(-err), err);
192 return;
193 }
Mathias Agopianf5a33922012-09-19 18:16:22 -0700194 err = mHwc.fbPost(mDisplayType, acquireFence, buf);
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700195 if (err != NO_ERROR) {
196 ALOGE("error posting framebuffer: %d", err);
197 }
198}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800199#endif
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700200
201void FramebufferSurface::freeBufferLocked(int slotIndex) {
202 ConsumerBase::freeBufferLocked(slotIndex);
203 if (slotIndex == mCurrentBufferSlot) {
204 mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
205 }
206}
207
Jesse Hall851cfe82013-03-20 13:44:00 -0700208void FramebufferSurface::onFrameCommitted() {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800209#ifdef USE_HWC2
210 if (mHasPendingRelease) {
211 sp<Fence> fence = mHwc.getRetireFence(mDisplayType);
212 if (fence->isValid()) {
213 status_t result = addReleaseFence(mPreviousBufferSlot,
214 mPreviousBuffer, fence);
215 ALOGE_IF(result != NO_ERROR, "onFrameCommitted: failed to add the"
216 " fence: %s (%d)", strerror(-result), result);
217 }
218 status_t result = releaseBufferLocked(mPreviousBufferSlot,
219 mPreviousBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
220 ALOGE_IF(result != NO_ERROR, "onFrameCommitted: error releasing buffer:"
221 " %s (%d)", strerror(-result), result);
222
223 mPreviousBuffer.clear();
224 mHasPendingRelease = false;
225 }
226#else
Jesse Hall851cfe82013-03-20 13:44:00 -0700227 sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
Jesse Hall13f01cb2013-03-20 11:37:21 -0700228 if (fence->isValid() &&
229 mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
Lajos Molnarc5d7b7d2013-05-03 14:50:50 -0700230 status_t err = addReleaseFence(mCurrentBufferSlot,
231 mCurrentBuffer, fence);
Jesse Hall13f01cb2013-03-20 11:37:21 -0700232 ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
233 strerror(-err), err);
Mathias Agopianda27af92012-09-13 18:17:13 -0700234 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800235#endif
Mathias Agopianda27af92012-09-13 18:17:13 -0700236}
237
Dan Stoza9e56aa02015-11-02 13:00:03 -0800238#ifndef USE_HWC2
Mathias Agopian3e876012012-06-07 17:52:54 -0700239status_t FramebufferSurface::compositionComplete()
240{
Andy McFaddenb0d1dd32012-09-10 14:08:09 -0700241 return mHwc.fbCompositionComplete();
Mathias Agopian3e876012012-06-07 17:52:54 -0700242}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800243#endif
Mathias Agopian3e876012012-06-07 17:52:54 -0700244
Dan Stozaf10c46e2014-11-11 10:32:31 -0800245void FramebufferSurface::dumpAsString(String8& result) const {
Jamie Gennis1a4d8832012-08-02 20:11:05 -0700246 ConsumerBase::dump(result);
Mathias Agopian3e876012012-06-07 17:52:54 -0700247}
248
Mathias Agopian74d211a2013-04-22 16:55:35 +0200249void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const
Jesse Hall7adb0f82013-03-06 16:13:49 -0800250{
Dan Stoza9e56aa02015-11-02 13:00:03 -0800251#ifndef USE_HWC2
Jesse Hall7adb0f82013-03-06 16:13:49 -0800252 mHwc.fbDump(result);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800253#endif
Mathias Agopian74d211a2013-04-22 16:55:35 +0200254 ConsumerBase::dumpLocked(result, prefix);
Jesse Hall7adb0f82013-03-06 16:13:49 -0800255}
256
Dan Stoza9e56aa02015-11-02 13:00:03 -0800257#ifdef USE_HWC2
258const sp<Fence>& FramebufferSurface::getClientTargetAcquireFence() const {
259 return mCurrentFence;
260}
261#endif
262
Mathias Agopian3e876012012-06-07 17:52:54 -0700263// ----------------------------------------------------------------------------
264}; // namespace android
265// ----------------------------------------------------------------------------