diff options
Diffstat (limited to 'libs/gui')
33 files changed, 5994 insertions, 0 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index f1d1346366..e06cb5ffa0 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -11,9 +11,15 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +cc_library_headers { + name: "libgui_headers", + vendor_available: true, + export_include_dirs: ["include"], +} cc_library_shared { name: "libgui", + vendor_available: true, clang: true, cppflags: [ @@ -117,13 +123,23 @@ cc_library_shared { "android.hardware.configstore-utils", ], + header_libs: [ + "libgui_headers", + ], + export_shared_lib_headers: [ "libbinder", + "libEGL", + "libnativewindow", "libui", "android.hidl.token@1.0-utils", "android.hardware.graphics.bufferqueue@1.0", ], + export_header_lib_headers: [ + "libgui_headers", + ], + export_include_dirs: [ "include", ], diff --git a/libs/gui/include/gui/BufferItem.h b/libs/gui/include/gui/BufferItem.h new file mode 100644 index 0000000000..55637a9be4 --- /dev/null +++ b/libs/gui/include/gui/BufferItem.h @@ -0,0 +1,129 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERITEM_H +#define ANDROID_GUI_BUFFERITEM_H + +#include <ui/FenceTime.h> +#include <ui/Rect.h> +#include <ui/Region.h> + +#include <system/graphics.h> + +#include <utils/Flattenable.h> +#include <utils/StrongPointer.h> + +namespace android { + +class Fence; +class GraphicBuffer; + +class BufferItem : public Flattenable<BufferItem> { + friend class Flattenable<BufferItem>; + size_t getPodSize() const; + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + + public: + // The default value of mBuf, used to indicate this doesn't correspond to a slot. + enum { INVALID_BUFFER_SLOT = -1 }; + BufferItem(); + ~BufferItem(); + BufferItem(const BufferItem&) = default; + BufferItem& operator=(const BufferItem&) = default; + + static const char* scalingModeName(uint32_t scalingMode); + + // mGraphicBuffer points to the buffer allocated for this slot, or is NULL + // if the buffer in this slot has been acquired in the past (see + // BufferSlot.mAcquireCalled). + sp<GraphicBuffer> mGraphicBuffer; + + // mFence is a fence that will signal when the buffer is idle. + sp<Fence> mFence; + + // The std::shared_ptr<FenceTime> wrapper around mFence. + std::shared_ptr<FenceTime> mFenceTime{FenceTime::NO_FENCE}; + + // mCrop is the current crop rectangle for this buffer slot. + Rect mCrop; + + // mTransform is the current transform flags for this buffer slot. + // refer to NATIVE_WINDOW_TRANSFORM_* in <window.h> + uint32_t mTransform; + + // mScalingMode is the current scaling mode for this buffer slot. + // refer to NATIVE_WINDOW_SCALING_* in <window.h> + uint32_t mScalingMode; + + // mTimestamp is the current timestamp for this buffer slot. This gets + // to set by queueBuffer each time this slot is queued. This value + // is guaranteed to be monotonically increasing for each newly + // acquired buffer. + int64_t mTimestamp; + + // mIsAutoTimestamp indicates whether mTimestamp was generated + // automatically when the buffer was queued. + bool mIsAutoTimestamp; + + // mDataSpace is the current dataSpace value for this buffer slot. This gets + // set by queueBuffer each time this slot is queued. The meaning of the + // dataSpace is format-dependent. + android_dataspace mDataSpace; + + // mFrameNumber is the number of the queued frame for this slot. + uint64_t mFrameNumber; + + // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT). + int mSlot; + + // mIsDroppable whether this buffer was queued with the + // property that it can be replaced by a new buffer for the purpose of + // making sure dequeueBuffer() won't block. + // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer + // was queued. + bool mIsDroppable; + + // Indicates whether this buffer has been seen by a consumer yet + bool mAcquireCalled; + + // Indicates this buffer must be transformed by the inverse transform of the screen + // it is displayed onto. This is applied after mTransform. + bool mTransformToDisplayInverse; + + // Describes the portion of the surface that has been modified since the + // previous frame + Region mSurfaceDamage; + + // Indicates that the consumer should acquire the next frame as soon as it + // can and not wait for a frame to become available. This is only relevant + // in shared buffer mode. + bool mAutoRefresh; + + // Indicates that this buffer was queued by the producer. When in shared + // buffer mode acquire() can return a BufferItem that wasn't in the queue. + bool mQueuedBuffer; + + // Indicates that this BufferItem contains a stale buffer which has already + // been released by the BufferQueue. + bool mIsStale; +}; + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h new file mode 100644 index 0000000000..217fe6ad81 --- /dev/null +++ b/libs/gui/include/gui/BufferItemConsumer.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H +#define ANDROID_GUI_BUFFERITEMCONSUMER_H + +#include <gui/ConsumerBase.h> +#include <gui/BufferQueue.h> + +#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer" + +namespace android { + +class String8; + +/** + * BufferItemConsumer is a BufferQueue consumer endpoint that allows clients + * access to the whole BufferItem entry from BufferQueue. Multiple buffers may + * be acquired at once, to be used concurrently by the client. This consumer can + * operate either in synchronous or asynchronous mode. + */ +class BufferItemConsumer: public ConsumerBase +{ + public: + typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; + + struct BufferFreedListener : public virtual RefBase { + virtual void onBufferFreed(const wp<GraphicBuffer>& graphicBuffer) = 0; + }; + + enum { DEFAULT_MAX_BUFFERS = -1 }; + enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT }; + enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE }; + + // Create a new buffer item consumer. The consumerUsage parameter determines + // the consumer usage flags passed to the graphics allocator. The + // bufferCount parameter specifies how many buffers can be locked for user + // access at the same time. + // controlledByApp tells whether this consumer is controlled by the + // application. + BufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, + uint32_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS, + bool controlledByApp = false); + + ~BufferItemConsumer() override; + + // set the name of the BufferItemConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // setBufferFreedListener sets the listener object that will be notified + // when an old buffer is being freed. + void setBufferFreedListener(const wp<BufferFreedListener>& listener); + + // Gets the next graphics buffer from the producer, filling out the + // passed-in BufferItem structure. Returns NO_BUFFER_AVAILABLE if the queue + // of buffers is empty, and INVALID_OPERATION if the maximum number of + // buffers is already acquired. + // + // Only a fixed number of buffers can be acquired at a time, determined by + // the construction-time bufferCount parameter. If INVALID_OPERATION is + // returned by acquireBuffer, then old buffers must be returned to the + // queue by calling releaseBuffer before more buffers can be acquired. + // + // If waitForFence is true, and the acquired BufferItem has a valid fence object, + // acquireBuffer will wait on the fence with no timeout before returning. + status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen, + bool waitForFence = true); + + // Returns an acquired buffer to the queue, allowing it to be reused. Since + // only a fixed number of buffers may be acquired at a time, old buffers + // must be released by calling releaseBuffer to ensure new buffers can be + // acquired by acquireBuffer. Once a BufferItem is released, the caller must + // not access any members of the BufferItem, and should immediately remove + // all of its references to the BufferItem itself. + status_t releaseBuffer(const BufferItem &item, + const sp<Fence>& releaseFence = Fence::NO_FENCE); + + private: + void freeBufferLocked(int slotIndex) override; + + // mBufferFreedListener is the listener object that will be called when + // an old buffer is being freed. If it is not NULL it will be called from + // freeBufferLocked. + wp<BufferFreedListener> mBufferFreedListener; +}; + +} // namespace android + +#endif // ANDROID_GUI_CPUCONSUMER_H diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h new file mode 100644 index 0000000000..ba5cbf7eb4 --- /dev/null +++ b/libs/gui/include/gui/BufferQueue.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUE_H +#define ANDROID_GUI_BUFFERQUEUE_H + +#include <gui/BufferItem.h> +#include <gui/BufferQueueDefs.h> +#include <gui/IGraphicBufferConsumer.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/IConsumerListener.h> + +namespace android { + +class BufferQueue { +public: + // BufferQueue will keep track of at most this value of buffers. + // Attempts at runtime to increase the number of buffers past this will fail. + enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS }; + // Used as a placeholder slot# when the value isn't pointing to an existing buffer. + enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT }; + // Alias to <IGraphicBufferConsumer.h> -- please scope from there in future code! + enum { + NO_BUFFER_AVAILABLE = IGraphicBufferConsumer::NO_BUFFER_AVAILABLE, + PRESENT_LATER = IGraphicBufferConsumer::PRESENT_LATER, + }; + + // When in async mode we reserve two slots in order to guarantee that the + // producer and consumer can run asynchronously. + enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 }; + + // for backward source compatibility + typedef ::android::ConsumerListener ConsumerListener; + + // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak + // reference to the actual consumer object. It forwards all calls to that + // consumer object so long as it exists. + // + // This class exists to avoid having a circular reference between the + // BufferQueue object and the consumer object. The reason this can't be a weak + // reference in the BufferQueue class is because we're planning to expose the + // consumer side of a BufferQueue as a binder interface, which doesn't support + // weak references. + class ProxyConsumerListener : public BnConsumerListener { + public: + explicit ProxyConsumerListener(const wp<ConsumerListener>& consumerListener); + ~ProxyConsumerListener() override; + void onDisconnect() override; + void onFrameAvailable(const BufferItem& item) override; + void onFrameReplaced(const BufferItem& item) override; + void onBuffersReleased() override; + void onSidebandStreamChanged() override; + void addAndGetFrameTimestamps( + const NewFrameEventsEntry* newTimestamps, + FrameEventHistoryDelta* outDelta) override; + private: + // mConsumerListener is a weak reference to the IConsumerListener. This is + // the raison d'etre of ProxyConsumerListener. + wp<ConsumerListener> mConsumerListener; + }; + + // BufferQueue manages a pool of gralloc memory slots to be used by + // producers and consumers. allocator is used to allocate all the + // needed gralloc buffers. + static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer, + sp<IGraphicBufferConsumer>* outConsumer, + bool consumerIsSurfaceFlinger = false); + + BufferQueue() = delete; // Create through createBufferQueue +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_BUFFERQUEUE_H diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h new file mode 100644 index 0000000000..f194bdf758 --- /dev/null +++ b/libs/gui/include/gui/BufferQueueConsumer.h @@ -0,0 +1,189 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUECONSUMER_H +#define ANDROID_GUI_BUFFERQUEUECONSUMER_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <gui/BufferQueueDefs.h> +#include <gui/IGraphicBufferConsumer.h> +#include <utils/String8.h> + +namespace android { + +class BufferQueueCore; + +class BufferQueueConsumer : public BnGraphicBufferConsumer { + +public: + BufferQueueConsumer(const sp<BufferQueueCore>& core); + ~BufferQueueConsumer() override; + + // acquireBuffer attempts to acquire ownership of the next pending buffer in + // the BufferQueue. If no buffer is pending then it returns + // NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the + // information about the buffer is returned in BufferItem. If the buffer + // returned had previously been acquired then the BufferItem::mGraphicBuffer + // field of buffer is set to NULL and it is assumed that the consumer still + // holds a reference to the buffer. + // + // If expectedPresent is nonzero, it indicates the time when the buffer + // will be displayed on screen. If the buffer's timestamp is farther in the + // future, the buffer won't be acquired, and PRESENT_LATER will be + // returned. The presentation time is in nanoseconds, and the time base + // is CLOCK_MONOTONIC. + virtual status_t acquireBuffer(BufferItem* outBuffer, + nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override; + + // See IGraphicBufferConsumer::detachBuffer + virtual status_t detachBuffer(int slot); + + // See IGraphicBufferConsumer::attachBuffer + virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer); + + // releaseBuffer releases a buffer slot from the consumer back to the + // BufferQueue. This may be done while the buffer's contents are still + // being accessed. The fence will signal when the buffer is no longer + // in use. frameNumber is used to indentify the exact buffer returned. + // + // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free + // any references to the just-released buffer that it might have, as if it + // had received a onBuffersReleased() call with a mask set for the released + // buffer. + // + // Note that the dependencies on EGL will be removed once we switch to using + // the Android HW Sync HAL. + virtual status_t releaseBuffer(int slot, uint64_t frameNumber, + const sp<Fence>& releaseFence, EGLDisplay display, + EGLSyncKHR fence); + + // connect connects a consumer to the BufferQueue. Only one + // consumer may be connected, and when that consumer disconnects the + // BufferQueue is placed into the "abandoned" state, causing most + // interactions with the BufferQueue by the producer to fail. + // controlledByApp indicates whether the consumer is controlled by + // the application. + // + // consumerListener may not be NULL. + virtual status_t connect(const sp<IConsumerListener>& consumerListener, + bool controlledByApp); + + // disconnect disconnects a consumer from the BufferQueue. All + // buffers will be freed and the BufferQueue is placed in the "abandoned" + // state, causing most interactions with the BufferQueue by the producer to + // fail. + virtual status_t disconnect(); + + // getReleasedBuffers sets the value pointed to by outSlotMask to a bit mask + // indicating which buffer slots have been released by the BufferQueue + // but have not yet been released by the consumer. + // + // This should be called from the onBuffersReleased() callback. + virtual status_t getReleasedBuffers(uint64_t* outSlotMask); + + // setDefaultBufferSize is used to set the size of buffers returned by + // dequeueBuffer when a width and height of zero is requested. Default + // is 1x1. + virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // see IGraphicBufferConsumer::setMaxBufferCount + virtual status_t setMaxBufferCount(int bufferCount); + + // setMaxAcquiredBufferCount sets the maximum number of buffers that can + // be acquired by the consumer at one time (default 1). This call will + // fail if a producer is connected to the BufferQueue. + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); + + // setConsumerName sets the name used in logging + status_t setConsumerName(const String8& name) override; + + // setDefaultBufferFormat allows the BufferQueue to create + // GraphicBuffers of a defaultFormat if no format is specified + // in dequeueBuffer. The initial default is HAL_PIXEL_FORMAT_RGBA_8888. + virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat); + + // setDefaultBufferDataSpace allows the BufferQueue to create + // GraphicBuffers of a defaultDataSpace if no data space is specified + // in queueBuffer. + // The initial default is HAL_DATASPACE_UNKNOWN + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace); + + // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer. + // These are merged with the bits passed to dequeueBuffer. The values are + // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0. + virtual status_t setConsumerUsageBits(uint32_t usage); + + // setConsumerIsProtected will turn on an internal bit that indicates whether + // the consumer can handle protected gralloc buffers (i.e. with + // GRALLOC_USAGE_PROTECTED set). IGraphicBufferProducer can query this + // capability using NATIVE_WINDOW_CONSUMER_IS_PROTECTED. + virtual status_t setConsumerIsProtected(bool isProtected); + + // setTransformHint bakes in rotation to buffers so overlays can be used. + // The values are enumerated in window.h, e.g. + // NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 (no transform). + virtual status_t setTransformHint(uint32_t hint); + + // Retrieve the sideband buffer stream, if any. + status_t getSidebandStream(sp<NativeHandle>* outStream) const override; + + // See IGraphicBufferConsumer::getOccupancyHistory + virtual status_t getOccupancyHistory(bool forceFlush, + std::vector<OccupancyTracker::Segment>* outHistory) override; + + // See IGraphicBufferConsumer::discardFreeBuffers + virtual status_t discardFreeBuffers() override; + + // dump our state in a String + status_t dumpState(const String8& prefix, String8* outResult) const override; + + // Functions required for backwards compatibility. + // These will be modified/renamed in IGraphicBufferConsumer and will be + // removed from this class at that time. See b/13306289. + + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, + EGLDisplay display, EGLSyncKHR fence, + const sp<Fence>& releaseFence) { + return releaseBuffer(buf, frameNumber, releaseFence, display, fence); + } + + virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, + bool controlledByApp) { + return connect(consumer, controlledByApp); + } + + virtual status_t consumerDisconnect() { return disconnect(); } + + // End functions required for backwards compatibility + +private: + sp<BufferQueueCore> mCore; + + // This references mCore->mSlots. Lock mCore->mMutex while accessing. + BufferQueueDefs::SlotsType& mSlots; + + // This is a cached copy of the name stored in the BufferQueueCore. + // It's updated during setConsumerName. + String8 mConsumerName; + +}; // class BufferQueueConsumer + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h new file mode 100644 index 0000000000..dd8b992ce1 --- /dev/null +++ b/libs/gui/include/gui/BufferQueueCore.h @@ -0,0 +1,343 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUECORE_H +#define ANDROID_GUI_BUFFERQUEUECORE_H + +#include <gui/BufferItem.h> +#include <gui/BufferQueueDefs.h> +#include <gui/BufferSlot.h> +#include <gui/OccupancyTracker.h> + +#include <utils/Condition.h> +#include <utils/Mutex.h> +#include <utils/NativeHandle.h> +#include <utils/RefBase.h> +#include <utils/String8.h> +#include <utils/StrongPointer.h> +#include <utils/Trace.h> +#include <utils/Vector.h> + +#include <list> +#include <set> + +#define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) + +#define ATRACE_BUFFER_INDEX(index) \ + if (ATRACE_ENABLED()) { \ + char ___traceBuf[1024]; \ + snprintf(___traceBuf, 1024, "%s: %d", \ + mCore->mConsumerName.string(), (index)); \ + android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ + } + +namespace android { + +class IConsumerListener; +class IProducerListener; + +class BufferQueueCore : public virtual RefBase { + + friend class BufferQueueProducer; + friend class BufferQueueConsumer; + +public: + // Used as a placeholder slot number when the value isn't pointing to an + // existing buffer. + enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT }; + + // We reserve two slots in order to guarantee that the producer and + // consumer can run asynchronously. + enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 }; + + enum { + // The API number used to indicate the currently connected producer + CURRENTLY_CONNECTED_API = -1, + + // The API number used to indicate that no producer is connected + NO_CONNECTED_API = 0, + }; + + typedef Vector<BufferItem> Fifo; + + // BufferQueueCore manages a pool of gralloc memory slots to be used by + // producers and consumers. + BufferQueueCore(); + virtual ~BufferQueueCore(); + +private: + // Dump our state in a string + void dumpState(const String8& prefix, String8* outResult) const; + + // getMinUndequeuedBufferCountLocked returns the minimum number of buffers + // that must remain in a state other than DEQUEUED. The async parameter + // tells whether we're in asynchronous mode. + int getMinUndequeuedBufferCountLocked() const; + + // getMinMaxBufferCountLocked returns the minimum number of buffers allowed + // given the current BufferQueue state. The async parameter tells whether + // we're in asynchonous mode. + int getMinMaxBufferCountLocked() const; + + // getMaxBufferCountLocked returns the maximum number of buffers that can be + // allocated at once. This value depends on the following member variables: + // + // mMaxDequeuedBufferCount + // mMaxAcquiredBufferCount + // mMaxBufferCount + // mAsyncMode + // mDequeueBufferCannotBlock + // + // Any time one of these member variables is changed while a producer is + // connected, mDequeueCondition must be broadcast. + int getMaxBufferCountLocked() const; + + // This performs the same computation but uses the given arguments instead + // of the member variables for mMaxBufferCount, mAsyncMode, and + // mDequeueBufferCannotBlock. + int getMaxBufferCountLocked(bool asyncMode, + bool dequeueBufferCannotBlock, int maxBufferCount) const; + + // clearBufferSlotLocked frees the GraphicBuffer and sync resources for the + // given slot. + void clearBufferSlotLocked(int slot); + + // freeAllBuffersLocked frees the GraphicBuffer and sync resources for + // all slots, even if they're currently dequeued, queued, or acquired. + void freeAllBuffersLocked(); + + // discardFreeBuffersLocked releases all currently-free buffers held by the + // queue, in order to reduce the memory consumption of the queue to the + // minimum possible without discarding data. + void discardFreeBuffersLocked(); + + // If delta is positive, makes more slots available. If negative, takes + // away slots. Returns false if the request can't be met. + bool adjustAvailableSlotsLocked(int delta); + + // waitWhileAllocatingLocked blocks until mIsAllocating is false. + void waitWhileAllocatingLocked() const; + +#if DEBUG_ONLY_CODE + // validateConsistencyLocked ensures that the free lists are in sync with + // the information stored in mSlots + void validateConsistencyLocked() const; +#endif + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of BufferQueueCore objects. It must be locked whenever any + // member variable is accessed. + mutable Mutex mMutex; + + // mIsAbandoned indicates that the BufferQueue will no longer be used to + // consume image buffers pushed to it using the IGraphicBufferProducer + // interface. It is initialized to false, and set to true in the + // consumerDisconnect method. A BufferQueue that is abandoned will return + // the NO_INIT error from all IGraphicBufferProducer methods capable of + // returning an error. + bool mIsAbandoned; + + // mConsumerControlledByApp indicates whether the connected consumer is + // controlled by the application. + bool mConsumerControlledByApp; + + // mConsumerName is a string used to identify the BufferQueue in log + // messages. It is set by the IGraphicBufferConsumer::setConsumerName + // method. + String8 mConsumerName; + + // mConsumerListener is used to notify the connected consumer of + // asynchronous events that it may wish to react to. It is initially + // set to NULL and is written by consumerConnect and consumerDisconnect. + sp<IConsumerListener> mConsumerListener; + + // mConsumerUsageBits contains flags that the consumer wants for + // GraphicBuffers. + uint32_t mConsumerUsageBits; + + // mConsumerIsProtected indicates the consumer is ready to handle protected + // buffer. + bool mConsumerIsProtected; + + // mConnectedApi indicates the producer API that is currently connected + // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated + // by the connect and disconnect methods. + int mConnectedApi; + // PID of the process which last successfully called connect(...) + pid_t mConnectedPid; + + // mLinkedToDeath is used to set a binder death notification on + // the producer. + sp<IProducerListener> mLinkedToDeath; + + // mConnectedProducerListener is used to handle the onBufferReleased + // notification. + sp<IProducerListener> mConnectedProducerListener; + + // mSlots is an array of buffer slots that must be mirrored on the producer + // side. This allows buffer ownership to be transferred between the producer + // and consumer without sending a GraphicBuffer over Binder. The entire + // array is initialized to NULL at construction time, and buffers are + // allocated for a slot when requestBuffer is called with that slot's index. + BufferQueueDefs::SlotsType mSlots; + + // mQueue is a FIFO of queued buffers used in synchronous mode. + Fifo mQueue; + + // mFreeSlots contains all of the slots which are FREE and do not currently + // have a buffer attached. + std::set<int> mFreeSlots; + + // mFreeBuffers contains all of the slots which are FREE and currently have + // a buffer attached. + std::list<int> mFreeBuffers; + + // mUnusedSlots contains all slots that are currently unused. They should be + // free and not have a buffer attached. + std::list<int> mUnusedSlots; + + // mActiveBuffers contains all slots which have a non-FREE buffer attached. + std::set<int> mActiveBuffers; + + // mDequeueCondition is a condition variable used for dequeueBuffer in + // synchronous mode. + mutable Condition mDequeueCondition; + + // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to + // block. This flag is set during connect when both the producer and + // consumer are controlled by the application. + bool mDequeueBufferCannotBlock; + + // mDefaultBufferFormat can be set so it will override the buffer format + // when it isn't specified in dequeueBuffer. + PixelFormat mDefaultBufferFormat; + + // mDefaultWidth holds the default width of allocated buffers. It is used + // in dequeueBuffer if a width and height of 0 are specified. + uint32_t mDefaultWidth; + + // mDefaultHeight holds the default height of allocated buffers. It is used + // in dequeueBuffer if a width and height of 0 are specified. + uint32_t mDefaultHeight; + + // mDefaultBufferDataSpace holds the default dataSpace of queued buffers. + // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN) + // is specified. + android_dataspace mDefaultBufferDataSpace; + + // mMaxBufferCount is the limit on the number of buffers that will be + // allocated at one time. This limit can be set by the consumer. + int mMaxBufferCount; + + // mMaxAcquiredBufferCount is the number of buffers that the consumer may + // acquire at one time. It defaults to 1, and can be changed by the consumer + // via setMaxAcquiredBufferCount, but this may only be done while no + // producer is connected to the BufferQueue. This value is used to derive + // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer. + int mMaxAcquiredBufferCount; + + // mMaxDequeuedBufferCount is the number of buffers that the producer may + // dequeue at one time. It defaults to 1, and can be changed by the producer + // via setMaxDequeuedBufferCount. + int mMaxDequeuedBufferCount; + + // mBufferHasBeenQueued is true once a buffer has been queued. It is reset + // when something causes all buffers to be freed (e.g., changing the buffer + // count). + bool mBufferHasBeenQueued; + + // mFrameCounter is the free running counter, incremented on every + // successful queueBuffer call and buffer allocation. + uint64_t mFrameCounter; + + // mTransformHint is used to optimize for screen rotations. + uint32_t mTransformHint; + + // mSidebandStream is a handle to the sideband buffer stream, if any + sp<NativeHandle> mSidebandStream; + + // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which + // releases mMutex while doing the allocation proper). Producers should not modify any of the + // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to + // false. + bool mIsAllocating; + + // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating + // becomes false. + mutable Condition mIsAllocatingCondition; + + // mAllowAllocation determines whether dequeueBuffer is allowed to allocate + // new buffers + bool mAllowAllocation; + + // mBufferAge tracks the age of the contents of the most recently dequeued + // buffer as the number of frames that have elapsed since it was last queued + uint64_t mBufferAge; + + // mGenerationNumber stores the current generation number of the attached + // producer. Any attempt to attach a buffer with a different generation + // number will fail. + uint32_t mGenerationNumber; + + // mAsyncMode indicates whether or not async mode is enabled. + // In async mode an extra buffer will be allocated to allow the producer to + // enqueue buffers without blocking. + bool mAsyncMode; + + // mSharedBufferMode indicates whether or not shared buffer mode is enabled. + bool mSharedBufferMode; + + // When shared buffer mode is enabled, this indicates whether the consumer + // should acquire buffers even if BufferQueue doesn't indicate that they are + // available. + bool mAutoRefresh; + + // When shared buffer mode is enabled, this tracks which slot contains the + // shared buffer. + int mSharedBufferSlot; + + // Cached data about the shared buffer in shared buffer mode + struct SharedBufferCache { + SharedBufferCache(Rect _crop, uint32_t _transform, + uint32_t _scalingMode, android_dataspace _dataspace) + : crop(_crop), + transform(_transform), + scalingMode(_scalingMode), + dataspace(_dataspace) { + } + + Rect crop; + uint32_t transform; + uint32_t scalingMode; + android_dataspace dataspace; + } mSharedBufferCache; + + // The slot of the last queued buffer + int mLastQueuedSlot; + + OccupancyTracker mOccupancyTracker; + + const uint64_t mUniqueId; + +}; // class BufferQueueCore + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/BufferQueueDefs.h b/libs/gui/include/gui/BufferQueueDefs.h new file mode 100644 index 0000000000..ffafb49615 --- /dev/null +++ b/libs/gui/include/gui/BufferQueueDefs.h @@ -0,0 +1,31 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUECOREDEFS_H +#define ANDROID_GUI_BUFFERQUEUECOREDEFS_H + +#include <gui/BufferSlot.h> +#include <ui/BufferQueueDefs.h> + +namespace android { + class BufferQueueCore; + + namespace BufferQueueDefs { + typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; + } // namespace BufferQueueDefs +} // namespace android + +#endif diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h new file mode 100644 index 0000000000..87bc8008e1 --- /dev/null +++ b/libs/gui/include/gui/BufferQueueProducer.h @@ -0,0 +1,254 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H +#define ANDROID_GUI_BUFFERQUEUEPRODUCER_H + +#include <gui/BufferQueueDefs.h> +#include <gui/IGraphicBufferProducer.h> + +namespace android { + +struct BufferSlot; + +class BufferQueueProducer : public BnGraphicBufferProducer, + private IBinder::DeathRecipient { +public: + friend class BufferQueue; // Needed to access binderDied + + BufferQueueProducer(const sp<BufferQueueCore>& core, bool consumerIsSurfaceFlinger = false); + ~BufferQueueProducer() override; + + // requestBuffer returns the GraphicBuffer for slot N. + // + // In normal operation, this is called the first time slot N is returned + // by dequeueBuffer. It must be called again if dequeueBuffer returns + // flags indicating that previously-returned buffers are no longer valid. + virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf); + + // see IGraphicsBufferProducer::setMaxDequeuedBufferCount + virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers); + + // see IGraphicsBufferProducer::setAsyncMode + virtual status_t setAsyncMode(bool async); + + // dequeueBuffer gets the next buffer slot index for the producer to use. + // If a buffer slot is available then that slot index is written to the + // location pointed to by the buf argument and a status of OK is returned. + // If no slot is available then a status of -EBUSY is returned and buf is + // unmodified. + // + // The outFence parameter will be updated to hold the fence associated with + // the buffer. The contents of the buffer must not be overwritten until the + // fence signals. If the fence is Fence::NO_FENCE, the buffer may be + // written immediately. + // + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. If width and height are both zero, the + // default values specified by setDefaultBufferSize() are used instead. + // + // If the format is 0, the default format will be used. + // + // The usage argument specifies gralloc buffer usage flags. The values + // are enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER. These + // will be merged with the usage flags specified by setConsumerUsageBits. + // + // The return value may be a negative error value or a non-negative + // collection of flags. If the flags are set, the return values are + // valid, but additional actions must be performed. + // + // If IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION is set, the + // producer must discard cached GraphicBuffer references for the slot + // returned in buf. + // If IGraphicBufferProducer::RELEASE_ALL_BUFFERS is set, the producer + // must discard cached GraphicBuffer references for all slots. + // + // In both cases, the producer will need to call requestBuffer to get a + // GraphicBuffer handle for the returned slot. + status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence, + uint32_t width, uint32_t height, PixelFormat format, + uint32_t usage, FrameEventHistoryDelta* outTimestamps) override; + + // See IGraphicBufferProducer::detachBuffer + virtual status_t detachBuffer(int slot); + + // See IGraphicBufferProducer::detachNextBuffer + virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence); + + // See IGraphicBufferProducer::attachBuffer + virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer); + + // queueBuffer returns a filled buffer to the BufferQueue. + // + // Additional data is provided in the QueueBufferInput struct. Notably, + // a timestamp must be provided for the buffer. The timestamp is in + // nanoseconds, and must be monotonically increasing. Its other semantics + // (zero point, etc) are producer-specific and should be documented by the + // producer. + // + // The caller may provide a fence that signals when all rendering + // operations have completed. Alternatively, NO_FENCE may be used, + // indicating that the buffer is ready immediately. + // + // Some values are returned in the output struct: the current settings + // for default width and height, the current transform hint, and the + // number of queued buffers. + virtual status_t queueBuffer(int slot, + const QueueBufferInput& input, QueueBufferOutput* output); + + // cancelBuffer returns a dequeued buffer to the BufferQueue, but doesn't + // queue it for use by the consumer. + // + // The buffer will not be overwritten until the fence signals. The fence + // will usually be the one obtained from dequeueBuffer. + virtual status_t cancelBuffer(int slot, const sp<Fence>& fence); + + // Query native window attributes. The "what" values are enumerated in + // window.h (e.g. NATIVE_WINDOW_FORMAT). + virtual int query(int what, int* outValue); + + // connect attempts to connect a producer API to the BufferQueue. This + // must be called before any other IGraphicBufferProducer methods are + // called except for getAllocator. A consumer must already be connected. + // + // This method will fail if connect was previously called on the + // BufferQueue and no corresponding disconnect call was made (i.e. if + // it's still connected to a producer). + // + // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU). + virtual status_t connect(const sp<IProducerListener>& listener, + int api, bool producerControlledByApp, QueueBufferOutput* output); + + // See IGraphicBufferProducer::disconnect + virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api); + + // Attaches a sideband buffer stream to the IGraphicBufferProducer. + // + // A sideband stream is a device-specific mechanism for passing buffers + // from the producer to the consumer without using dequeueBuffer/ + // queueBuffer. If a sideband stream is present, the consumer can choose + // whether to acquire buffers from the sideband stream or from the queued + // buffers. + // + // Passing NULL or a different stream handle will detach the previous + // handle if any. + virtual status_t setSidebandStream(const sp<NativeHandle>& stream); + + // See IGraphicBufferProducer::allocateBuffers + virtual void allocateBuffers(uint32_t width, uint32_t height, + PixelFormat format, uint32_t usage); + + // See IGraphicBufferProducer::allowAllocation + virtual status_t allowAllocation(bool allow); + + // See IGraphicBufferProducer::setGenerationNumber + virtual status_t setGenerationNumber(uint32_t generationNumber); + + // See IGraphicBufferProducer::getConsumerName + virtual String8 getConsumerName() const override; + + // See IGraphicBufferProducer::setSharedBufferMode + virtual status_t setSharedBufferMode(bool sharedBufferMode) override; + + // See IGraphicBufferProducer::setAutoRefresh + virtual status_t setAutoRefresh(bool autoRefresh) override; + + // See IGraphicBufferProducer::setDequeueTimeout + virtual status_t setDequeueTimeout(nsecs_t timeout) override; + + // See IGraphicBufferProducer::getLastQueuedBuffer + virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence, float outTransformMatrix[16]) override; + + // See IGraphicBufferProducer::getFrameTimestamps + virtual void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override; + + // See IGraphicBufferProducer::getUniqueId + virtual status_t getUniqueId(uint64_t* outId) const override; + +private: + // This is required by the IBinder::DeathRecipient interface + virtual void binderDied(const wp<IBinder>& who); + + // Returns the slot of the next free buffer if one is available or + // BufferQueueCore::INVALID_BUFFER_SLOT otherwise + int getFreeBufferLocked() const; + + // Returns the next free slot if one is available or + // BufferQueueCore::INVALID_BUFFER_SLOT otherwise + int getFreeSlotLocked() const; + + void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, + FrameEventHistoryDelta* outDelta); + + // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may + // block if there are no available slots and we are not in non-blocking + // mode (producer and consumer controlled by the application). If it blocks, + // it will release mCore->mMutex while blocked so that other operations on + // the BufferQueue may succeed. + enum class FreeSlotCaller { + Dequeue, + Attach, + }; + status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, int* found) const; + + sp<BufferQueueCore> mCore; + + // This references mCore->mSlots. Lock mCore->mMutex while accessing. + BufferQueueDefs::SlotsType& mSlots; + + // This is a cached copy of the name stored in the BufferQueueCore. + // It's updated during connect and dequeueBuffer (which should catch + // most updates). + String8 mConsumerName; + + uint32_t mStickyTransform; + + // This controls whether the GraphicBuffer pointer in the BufferItem is + // cleared after being queued + bool mConsumerIsSurfaceFlinger; + + // This saves the fence from the last queueBuffer, such that the + // next queueBuffer call can throttle buffer production. The prior + // queueBuffer's fence is not nessessarily available elsewhere, + // since the previous buffer might have already been acquired. + sp<Fence> mLastQueueBufferFence; + + Rect mLastQueuedCrop; + uint32_t mLastQueuedTransform; + + // Take-a-ticket system for ensuring that onFrame* callbacks are called in + // the order that frames are queued. While the BufferQueue lock + // (mCore->mMutex) is held, a ticket is retained by the producer. After + // dropping the BufferQueue lock, the producer must wait on the condition + // variable until the current callback ticket matches its retained ticket. + Mutex mCallbackMutex; + int mNextCallbackTicket; // Protected by mCore->mMutex + int mCurrentCallbackTicket; // Protected by mCallbackMutex + Condition mCallbackCondition; + + // Sets how long dequeueBuffer or attachBuffer will block if a buffer or + // slot is not yet available. + nsecs_t mDequeueTimeout; + +}; // class BufferQueueProducer + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/BufferSlot.h b/libs/gui/include/gui/BufferSlot.h new file mode 100644 index 0000000000..57704b1d09 --- /dev/null +++ b/libs/gui/include/gui/BufferSlot.h @@ -0,0 +1,237 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERSLOT_H +#define ANDROID_GUI_BUFFERSLOT_H + +#include <ui/Fence.h> +#include <ui/GraphicBuffer.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <utils/StrongPointer.h> + +namespace android { + +class Fence; + +// BufferState tracks the states in which a buffer slot can be. +struct BufferState { + + // All slots are initially FREE (not dequeued, queued, acquired, or shared). + BufferState() + : mDequeueCount(0), + mQueueCount(0), + mAcquireCount(0), + mShared(false) { + } + + uint32_t mDequeueCount; + uint32_t mQueueCount; + uint32_t mAcquireCount; + bool mShared; + + // A buffer can be in one of five states, represented as below: + // + // | mShared | mDequeueCount | mQueueCount | mAcquireCount | + // --------|---------|---------------|-------------|---------------| + // FREE | false | 0 | 0 | 0 | + // DEQUEUED| false | 1 | 0 | 0 | + // QUEUED | false | 0 | 1 | 0 | + // ACQUIRED| false | 0 | 0 | 1 | + // SHARED | true | any | any | any | + // + // FREE indicates that the buffer is available to be dequeued by the + // producer. The slot is "owned" by BufferQueue. It transitions to DEQUEUED + // when dequeueBuffer is called. + // + // DEQUEUED indicates that the buffer has been dequeued by the producer, but + // has not yet been queued or canceled. The producer may modify the + // buffer's contents as soon as the associated release fence is signaled. + // The slot is "owned" by the producer. It can transition to QUEUED (via + // queueBuffer or attachBuffer) or back to FREE (via cancelBuffer or + // detachBuffer). + // + // QUEUED indicates that the buffer has been filled by the producer and + // queued for use by the consumer. The buffer contents may continue to be + // modified for a finite time, so the contents must not be accessed until + // the associated fence is signaled. The slot is "owned" by BufferQueue. It + // can transition to ACQUIRED (via acquireBuffer) or to FREE (if another + // buffer is queued in asynchronous mode). + // + // ACQUIRED indicates that the buffer has been acquired by the consumer. As + // with QUEUED, the contents must not be accessed by the consumer until the + // acquire fence is signaled. The slot is "owned" by the consumer. It + // transitions to FREE when releaseBuffer (or detachBuffer) is called. A + // detached buffer can also enter the ACQUIRED state via attachBuffer. + // + // SHARED indicates that this buffer is being used in shared buffer + // mode. It can be in any combination of the other states at the same time, + // except for FREE (since that excludes being in any other state). It can + // also be dequeued, queued, or acquired multiple times. + + inline bool isFree() const { + return !isAcquired() && !isDequeued() && !isQueued(); + } + + inline bool isDequeued() const { + return mDequeueCount > 0; + } + + inline bool isQueued() const { + return mQueueCount > 0; + } + + inline bool isAcquired() const { + return mAcquireCount > 0; + } + + inline bool isShared() const { + return mShared; + } + + inline void reset() { + *this = BufferState(); + } + + const char* string() const; + + inline void dequeue() { + mDequeueCount++; + } + + inline void detachProducer() { + if (mDequeueCount > 0) { + mDequeueCount--; + } + } + + inline void attachProducer() { + mDequeueCount++; + } + + inline void queue() { + if (mDequeueCount > 0) { + mDequeueCount--; + } + mQueueCount++; + } + + inline void cancel() { + if (mDequeueCount > 0) { + mDequeueCount--; + } + } + + inline void freeQueued() { + if (mQueueCount > 0) { + mQueueCount--; + } + } + + inline void acquire() { + if (mQueueCount > 0) { + mQueueCount--; + } + mAcquireCount++; + } + + inline void acquireNotInQueue() { + mAcquireCount++; + } + + inline void release() { + if (mAcquireCount > 0) { + mAcquireCount--; + } + } + + inline void detachConsumer() { + if (mAcquireCount > 0) { + mAcquireCount--; + } + } + + inline void attachConsumer() { + mAcquireCount++; + } +}; + +struct BufferSlot { + + BufferSlot() + : mGraphicBuffer(nullptr), + mEglDisplay(EGL_NO_DISPLAY), + mBufferState(), + mRequestBufferCalled(false), + mFrameNumber(0), + mEglFence(EGL_NO_SYNC_KHR), + mFence(Fence::NO_FENCE), + mAcquireCalled(false), + mNeedsReallocation(false) { + } + + // mGraphicBuffer points to the buffer allocated for this slot or is NULL + // if no buffer has been allocated. + sp<GraphicBuffer> mGraphicBuffer; + + // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects. + EGLDisplay mEglDisplay; + + // mBufferState is the current state of this buffer slot. + BufferState mBufferState; + + // mRequestBufferCalled is used for validating that the producer did + // call requestBuffer() when told to do so. Technically this is not + // needed but useful for debugging and catching producer bugs. + bool mRequestBufferCalled; + + // mFrameNumber is the number of the queued frame for this slot. This + // is used to dequeue buffers in LRU order (useful because buffers + // may be released before their release fence is signaled). + uint64_t mFrameNumber; + + // mEglFence is the EGL sync object that must signal before the buffer + // associated with this buffer slot may be dequeued. It is initialized + // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a + // new sync object in releaseBuffer. (This is deprecated in favor of + // mFence, below.) + EGLSyncKHR mEglFence; + + // mFence is a fence which will signal when work initiated by the + // previous owner of the buffer is finished. When the buffer is FREE, + // the fence indicates when the consumer has finished reading + // from the buffer, or when the producer has finished writing if it + // called cancelBuffer after queueing some writes. When the buffer is + // QUEUED, it indicates when the producer has finished filling the + // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been + // passed to the consumer or producer along with ownership of the + // buffer, and mFence is set to NO_FENCE. + sp<Fence> mFence; + + // Indicates whether this buffer has been seen by a consumer yet + bool mAcquireCalled; + + // Indicates whether the buffer was re-allocated without notifying the + // producer. If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when + // dequeued to prevent the producer from using a stale cached buffer. + bool mNeedsReallocation; +}; + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h new file mode 100644 index 0000000000..d1a9b04ad6 --- /dev/null +++ b/libs/gui/include/gui/ConsumerBase.h @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CONSUMERBASE_H +#define ANDROID_GUI_CONSUMERBASE_H + +#include <gui/BufferQueueDefs.h> +#include <gui/IConsumerListener.h> +#include <gui/IGraphicBufferConsumer.h> +#include <gui/OccupancyTracker.h> + +#include <ui/PixelFormat.h> + +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/threads.h> + + +namespace android { +// ---------------------------------------------------------------------------- + +class String8; +class GraphicBuffer; + +// ConsumerBase is a base class for BufferQueue consumer end-points. It +// handles common tasks like management of the connection to the BufferQueue +// and the buffer pool. +class ConsumerBase : public virtual RefBase, + protected ConsumerListener { +public: + struct FrameAvailableListener : public virtual RefBase { + // See IConsumerListener::onFrame{Available,Replaced} + virtual void onFrameAvailable(const BufferItem& item) = 0; + virtual void onFrameReplaced(const BufferItem& /* item */) {} + }; + + ~ConsumerBase() override; + + // abandon frees all the buffers and puts the ConsumerBase into the + // 'abandoned' state. Once put in this state the ConsumerBase can never + // leave it. When in the 'abandoned' state, all methods of the + // IGraphicBufferProducer interface will fail with the NO_INIT error. + // + // Note that while calling this method causes all the buffers to be freed + // from the perspective of the the ConsumerBase, if there are additional + // references on the buffers (e.g. if a buffer is referenced by a client + // or by OpenGL ES as a texture) then those buffer will remain allocated. + void abandon(); + + // Returns true if the ConsumerBase is in the 'abandoned' state + bool isAbandoned(); + + // set the name of the ConsumerBase that will be used to identify it in + // log messages. + void setName(const String8& name); + + // dumpState writes the current state to a string. Child classes should add + // their state to the dump by overriding the dumpLocked method, which is + // called by these methods after locking the mutex. + void dumpState(String8& result) const; + void dumpState(String8& result, const char* prefix) const; + + // setFrameAvailableListener sets the listener object that will be notified + // when a new frame becomes available. + void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); + + // See IGraphicBufferConsumer::detachBuffer + status_t detachBuffer(int slot); + + // See IGraphicBufferConsumer::setDefaultBufferSize + status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // See IGraphicBufferConsumer::setDefaultBufferFormat + status_t setDefaultBufferFormat(PixelFormat defaultFormat); + + // See IGraphicBufferConsumer::setDefaultBufferDataSpace + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); + + // See IGraphicBufferConsumer::getOccupancyHistory + status_t getOccupancyHistory(bool forceFlush, + std::vector<OccupancyTracker::Segment>* outHistory); + + // See IGraphicBufferConsumer::discardFreeBuffers + status_t discardFreeBuffers(); + +private: + ConsumerBase(const ConsumerBase&); + void operator=(const ConsumerBase&); + +protected: + // ConsumerBase constructs a new ConsumerBase object to consume image + // buffers from the given IGraphicBufferConsumer. + // The controlledByApp flag indicates that this consumer is under the application's + // control. + explicit ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false); + + // onLastStrongRef gets called by RefBase just before the dtor of the most + // derived class. It is used to clean up the buffers so that ConsumerBase + // can coordinate the clean-up by calling into virtual methods implemented + // by the derived classes. This would not be possible from the + // ConsuemrBase dtor because by the time that gets called the derived + // classes have already been destructed. + // + // This methods should not need to be overridden by derived classes, but + // if they are overridden the ConsumerBase implementation must be called + // from the derived class. + virtual void onLastStrongRef(const void* id); + + // Implementation of the IConsumerListener interface. These + // calls are used to notify the ConsumerBase of asynchronous events in the + // BufferQueue. The onFrameAvailable, onFrameReplaced, and + // onBuffersReleased methods should not need to be overridden by derived + // classes, but if they are overridden the ConsumerBase implementation must + // be called from the derived class. The ConsumerBase version of + // onSidebandStreamChanged does nothing and can be overriden by derived + // classes if they want the notification. + virtual void onFrameAvailable(const BufferItem& item) override; + virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onBuffersReleased() override; + virtual void onSidebandStreamChanged() override; + + // freeBufferLocked frees up the given buffer slot. If the slot has been + // initialized this will release the reference to the GraphicBuffer in that + // slot. Otherwise it has no effect. + // + // Derived classes should override this method to clean up any state they + // keep per slot. If it is overridden, the derived class's implementation + // must call ConsumerBase::freeBufferLocked. + // + // This method must be called with mMutex locked. + virtual void freeBufferLocked(int slotIndex); + + // abandonLocked puts the BufferQueue into the abandoned state, causing + // all future operations on it to fail. This method rather than the public + // abandon method should be overridden by child classes to add abandon- + // time behavior. + // + // Derived classes should override this method to clean up any object + // state they keep (as opposed to per-slot state). If it is overridden, + // the derived class's implementation must call ConsumerBase::abandonLocked. + // + // This method must be called with mMutex locked. + virtual void abandonLocked(); + + // dumpLocked dumps the current state of the ConsumerBase object to the + // result string. Each line is prefixed with the string pointed to by the + // prefix argument. The buffer argument points to a buffer that may be + // used for intermediate formatting data, and the size of that buffer is + // indicated by the size argument. + // + // Derived classes should override this method to dump their internal + // state. If this method is overridden the derived class's implementation + // should call ConsumerBase::dumpLocked. + // + // This method must be called with mMutex locked. + virtual void dumpLocked(String8& result, const char* prefix) const; + + // acquireBufferLocked fetches the next buffer from the BufferQueue and + // updates the buffer slot for the buffer returned. + // + // Derived classes should override this method to perform any + // initialization that must take place the first time a buffer is assigned + // to a slot. If it is overridden the derived class's implementation must + // call ConsumerBase::acquireBufferLocked. + virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, + uint64_t maxFrameNumber = 0); + + // releaseBufferLocked relinquishes control over a buffer, returning that + // control to the BufferQueue. + // + // Derived classes should override this method to perform any cleanup that + // must take place when a buffer is released back to the BufferQueue. If + // it is overridden the derived class's implementation must call + // ConsumerBase::releaseBufferLocked. + virtual status_t releaseBufferLocked(int slot, + const sp<GraphicBuffer> graphicBuffer, + EGLDisplay display, EGLSyncKHR eglFence); + + // returns true iff the slot still has the graphicBuffer in it. + bool stillTracking(int slot, const sp<GraphicBuffer> graphicBuffer); + + // addReleaseFence* adds the sync points associated with a fence to the set + // of sync points that must be reached before the buffer in the given slot + // may be used after the slot has been released. This should be called by + // derived classes each time some asynchronous work is kicked off that + // references the buffer. + status_t addReleaseFence(int slot, + const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence); + status_t addReleaseFenceLocked(int slot, + const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence); + + // Slot contains the information and object references that + // ConsumerBase maintains about a BufferQueue buffer slot. + struct Slot { + // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if + // no Gralloc buffer is in the slot. + sp<GraphicBuffer> mGraphicBuffer; + + // mFence is a fence which will signal when the buffer associated with + // this buffer slot is no longer being used by the consumer and can be + // overwritten. The buffer can be dequeued before the fence signals; + // the producer is responsible for delaying writes until it signals. + sp<Fence> mFence; + + // the frame number of the last acquired frame for this slot + uint64_t mFrameNumber; + }; + + // mSlots stores the buffers that have been allocated by the BufferQueue + // for each buffer slot. It is initialized to null pointers, and gets + // filled in with the result of BufferQueue::acquire when the + // client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + Slot mSlots[BufferQueueDefs::NUM_BUFFER_SLOTS]; + + // mAbandoned indicates that the BufferQueue will no longer be used to + // consume images buffers pushed to it using the IGraphicBufferProducer + // interface. It is initialized to false, and set to true in the abandon + // method. A BufferQueue that has been abandoned will return the NO_INIT + // error from all IConsumerBase methods capable of returning an error. + bool mAbandoned; + + // mName is a string used to identify the ConsumerBase in log messages. + // It can be set by the setName method. + String8 mName; + + // mFrameAvailableListener is the listener object that will be called when a + // new frame becomes available. If it is not NULL it will be called from + // queueBuffer. + wp<FrameAvailableListener> mFrameAvailableListener; + + // The ConsumerBase has-a BufferQueue and is responsible for creating this object + // if none is supplied + sp<IGraphicBufferConsumer> mConsumer; + + // The final release fence of the most recent buffer released by + // releaseBufferLocked. + sp<Fence> mPrevFinalReleaseFence; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of ConsumerBase objects. It must be locked whenever the + // member variables are accessed or when any of the *Locked methods are + // called. + // + // This mutex is intended to be locked by derived classes. + mutable Mutex mMutex; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_CONSUMERBASE_H diff --git a/libs/gui/include/gui/CpuConsumer.h b/libs/gui/include/gui/CpuConsumer.h new file mode 100644 index 0000000000..58602bf321 --- /dev/null +++ b/libs/gui/include/gui/CpuConsumer.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CPUCONSUMER_H +#define ANDROID_GUI_CPUCONSUMER_H + +#include <system/window.h> + +#include <gui/ConsumerBase.h> +#include <gui/BufferQueue.h> + +#include <utils/Vector.h> + + +namespace android { + +class BufferQueue; +class GraphicBuffer; +class String8; + +/** + * CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU + * access to the underlying gralloc buffers provided by BufferQueue. Multiple + * buffers may be acquired by it at once, to be used concurrently by the + * CpuConsumer owner. Sets gralloc usage flags to be software-read-only. + * This queue is synchronous by default. + */ + +class CpuConsumer : public ConsumerBase +{ + public: + typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; + + struct LockedBuffer { + uint8_t *data; + uint32_t width; + uint32_t height; + PixelFormat format; + uint32_t stride; + Rect crop; + uint32_t transform; + uint32_t scalingMode; + int64_t timestamp; + android_dataspace dataSpace; + uint64_t frameNumber; + // this is the same as format, except for formats that are compatible with + // a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter + // case this contains that flexible format + PixelFormat flexFormat; + // Values below are only valid when using HAL_PIXEL_FORMAT_YCbCr_420_888 + // or compatible format, in which case LockedBuffer::data + // contains the Y channel, and stride is the Y channel stride. For other + // formats, these will all be 0. + uint8_t *dataCb; + uint8_t *dataCr; + uint32_t chromaStride; + uint32_t chromaStep; + + LockedBuffer() : + data(NULL), + width(0), + height(0), + format(PIXEL_FORMAT_NONE), + stride(0), + crop(Rect::EMPTY_RECT), + transform(0), + scalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), + timestamp(0), + dataSpace(HAL_DATASPACE_UNKNOWN), + frameNumber(0), + flexFormat(PIXEL_FORMAT_NONE), + dataCb(NULL), + dataCr(NULL), + chromaStride(0), + chromaStep(0) + {} + }; + + // Create a new CPU consumer. The maxLockedBuffers parameter specifies + // how many buffers can be locked for user access at the same time. + CpuConsumer(const sp<IGraphicBufferConsumer>& bq, + size_t maxLockedBuffers, bool controlledByApp = false); + + virtual ~CpuConsumer(); + + // set the name of the CpuConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // Gets the next graphics buffer from the producer and locks it for CPU use, + // filling out the passed-in locked buffer structure with the native pointer + // and metadata. Returns BAD_VALUE if no new buffer is available, and + // NOT_ENOUGH_DATA if the maximum number of buffers is already locked. + // + // Only a fixed number of buffers can be locked at a time, determined by the + // construction-time maxLockedBuffers parameter. If INVALID_OPERATION is + // returned by lockNextBuffer, then old buffers must be returned to the queue + // by calling unlockBuffer before more buffers can be acquired. + status_t lockNextBuffer(LockedBuffer *nativeBuffer); + + // Returns a locked buffer to the queue, allowing it to be reused. Since + // only a fixed number of buffers may be locked at a time, old buffers must + // be released by calling unlockBuffer to ensure new buffers can be acquired by + // lockNextBuffer. + status_t unlockBuffer(const LockedBuffer &nativeBuffer); + + private: + // Maximum number of buffers that can be locked at a time + size_t mMaxLockedBuffers; + + status_t releaseAcquiredBufferLocked(size_t lockedIdx); + + virtual void freeBufferLocked(int slotIndex); + + // Tracking for buffers acquired by the user + struct AcquiredBuffer { + // Need to track the original mSlot index and the buffer itself because + // the mSlot entry may be freed/reused before the acquired buffer is + // released. + int mSlot; + sp<GraphicBuffer> mGraphicBuffer; + void *mBufferPointer; + + AcquiredBuffer() : + mSlot(BufferQueue::INVALID_BUFFER_SLOT), + mBufferPointer(NULL) { + } + }; + Vector<AcquiredBuffer> mAcquiredBuffers; + + // Count of currently locked buffers + size_t mCurrentLockedBuffers; + +}; + +} // namespace android + +#endif // ANDROID_GUI_CPUCONSUMER_H diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h new file mode 100644 index 0000000000..32ce59a765 --- /dev/null +++ b/libs/gui/include/gui/DisplayEventReceiver.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_DISPLAY_EVENT_H +#define ANDROID_GUI_DISPLAY_EVENT_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> +#include <utils/Timers.h> + +#include <binder/IInterface.h> +#include <gui/ISurfaceComposer.h> + +// ---------------------------------------------------------------------------- + +namespace android { + +// ---------------------------------------------------------------------------- + +class IDisplayEventConnection; + +namespace gui { +class BitTube; +} // namespace gui + +static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) { + return static_cast<uint32_t>(c1) << 24 | + static_cast<uint32_t>(c2) << 16 | + static_cast<uint32_t>(c3) << 8 | + static_cast<uint32_t>(c4); +} + +// ---------------------------------------------------------------------------- +class DisplayEventReceiver { +public: + enum { + DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'), + DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'), + }; + + struct Event { + + struct Header { + uint32_t type; + uint32_t id; + nsecs_t timestamp __attribute__((aligned(8))); + }; + + struct VSync { + uint32_t count; + }; + + struct Hotplug { + bool connected; + }; + + Header header; + union { + VSync vsync; + Hotplug hotplug; + }; + }; + +public: + /* + * DisplayEventReceiver creates and registers an event connection with + * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate + * or requestNextVsync to receive them. + * Other events start being delivered immediately. + */ + DisplayEventReceiver( + ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp); + + /* + * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events + * stop being delivered immediately. Note that the queue could have + * some events pending. These will be delivered. + */ + ~DisplayEventReceiver(); + + /* + * initCheck returns the state of DisplayEventReceiver after construction. + */ + status_t initCheck() const; + + /* + * getFd returns the file descriptor to use to receive events. + * OWNERSHIP IS RETAINED by DisplayEventReceiver. DO NOT CLOSE this + * file-descriptor. + */ + int getFd() const; + + /* + * getEvents reads events from the queue and returns how many events were + * read. Returns 0 if there are no more events or a negative error code. + * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it + * should be destroyed and getEvents() shouldn't be called again. + */ + ssize_t getEvents(Event* events, size_t count); + static ssize_t getEvents(gui::BitTube* dataChannel, Event* events, size_t count); + + /* + * sendEvents write events to the queue and returns how many events were + * written. + */ + static ssize_t sendEvents(gui::BitTube* dataChannel, Event const* events, size_t count); + + /* + * setVsyncRate() sets the Event::VSync delivery rate. A value of + * 1 returns every Event::VSync. A value of 2 returns every other event, + * etc... a value of 0 returns no event unless requestNextVsync() has + * been called. + */ + status_t setVsyncRate(uint32_t count); + + /* + * requestNextVsync() schedules the next Event::VSync. It has no effect + * if the vsync rate is > 0. + */ + status_t requestNextVsync(); + +private: + sp<IDisplayEventConnection> mEventConnection; + std::unique_ptr<gui::BitTube> mDataChannel; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_DISPLAY_EVENT_H diff --git a/libs/gui/include/gui/FrameTimestamps.h b/libs/gui/include/gui/FrameTimestamps.h new file mode 100644 index 0000000000..9716be4bfd --- /dev/null +++ b/libs/gui/include/gui/FrameTimestamps.h @@ -0,0 +1,337 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_FRAMETIMESTAMPS_H +#define ANDROID_GUI_FRAMETIMESTAMPS_H + +#include <ui/FenceTime.h> +#include <utils/Flattenable.h> +#include <utils/StrongPointer.h> +#include <utils/Timers.h> + +#include <array> +#include <bitset> +#include <vector> + +namespace android { + +struct FrameEvents; +class FrameEventHistoryDelta; +class String8; + + +// Identifiers for all the events that may be recorded or reported. +enum class FrameEvent { + POSTED, + REQUESTED_PRESENT, + LATCH, + ACQUIRE, + FIRST_REFRESH_START, + LAST_REFRESH_START, + GPU_COMPOSITION_DONE, + DISPLAY_PRESENT, + DEQUEUE_READY, + RELEASE, + EVENT_COUNT, // Not an actual event. +}; + + +// A collection of timestamps corresponding to a single frame. +struct FrameEvents { + static constexpr auto EVENT_COUNT = + static_cast<size_t>(FrameEvent::EVENT_COUNT); + static_assert(EVENT_COUNT <= 32, "Event count sanity check failed."); + static constexpr nsecs_t TIMESTAMP_PENDING = -2; + + static inline bool isValidTimestamp(nsecs_t time) { + return time != TIMESTAMP_PENDING; + } + + bool hasPostedInfo() const; + bool hasRequestedPresentInfo() const; + bool hasLatchInfo() const; + bool hasFirstRefreshStartInfo() const; + bool hasLastRefreshStartInfo() const; + bool hasAcquireInfo() const; + bool hasGpuCompositionDoneInfo() const; + bool hasDisplayPresentInfo() const; + bool hasReleaseInfo() const; + bool hasDequeueReadyInfo() const; + + void checkFencesForCompletion(); + void dump(String8& outString) const; + + bool valid{false}; + int connectId{0}; + uint64_t frameNumber{0}; + + // Whether or not certain points in the frame's life cycle have been + // encountered help us determine if timestamps aren't available because + // a) we'll just never get them or b) they're not ready yet. + bool addPostCompositeCalled{false}; + bool addReleaseCalled{false}; + + nsecs_t postedTime{TIMESTAMP_PENDING}; + nsecs_t requestedPresentTime{TIMESTAMP_PENDING}; + nsecs_t latchTime{TIMESTAMP_PENDING}; + nsecs_t firstRefreshStartTime{TIMESTAMP_PENDING}; + nsecs_t lastRefreshStartTime{TIMESTAMP_PENDING}; + nsecs_t dequeueReadyTime{TIMESTAMP_PENDING}; + + std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE}; + std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE}; + std::shared_ptr<FenceTime> displayPresentFence{FenceTime::NO_FENCE}; + std::shared_ptr<FenceTime> releaseFence{FenceTime::NO_FENCE}; +}; + +struct CompositorTiming { + nsecs_t deadline{0}; + nsecs_t interval{16666667}; + nsecs_t presentLatency{16666667}; +}; + +// A short history of frames that are synchronized between the consumer and +// producer via deltas. +class FrameEventHistory { +public: + virtual ~FrameEventHistory(); + + FrameEvents* getFrame(uint64_t frameNumber); + FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint); + void checkFencesForCompletion(); + void dump(String8& outString) const; + + static constexpr size_t MAX_FRAME_HISTORY = 8; + +protected: + std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames; + + CompositorTiming mCompositorTiming; +}; + + +// The producer's interface to FrameEventHistory +class ProducerFrameEventHistory : public FrameEventHistory { +public: + ~ProducerFrameEventHistory() override; + + // Public for testing. + static nsecs_t snapToNextTick( + nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval); + + nsecs_t getNextCompositeDeadline(const nsecs_t now) const; + nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; } + nsecs_t getCompositeToPresentLatency() const { + return mCompositorTiming.presentLatency; + } + + // virtual for testing. + virtual void updateAcquireFence( + uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire); + void applyDelta(const FrameEventHistoryDelta& delta); + + void updateSignalTimes(); + +protected: + void applyFenceDelta(FenceTimeline* timeline, + std::shared_ptr<FenceTime>* dst, + const FenceTime::Snapshot& src) const; + + // virtual for testing. + virtual std::shared_ptr<FenceTime> createFenceTime( + const sp<Fence>& fence) const; + + size_t mAcquireOffset{0}; + + // The consumer updates it's timelines in Layer and SurfaceFlinger since + // they can coordinate shared timelines better. The producer doesn't have + // shared timelines though, so just let it own and update all of them. + FenceTimeline mAcquireTimeline; + FenceTimeline mGpuCompositionDoneTimeline; + FenceTimeline mPresentTimeline; + FenceTimeline mReleaseTimeline; +}; + + +// Used by the consumer to create a new frame event record that is +// partially complete. +struct NewFrameEventsEntry { + uint64_t frameNumber{0}; + nsecs_t postedTime{0}; + nsecs_t requestedPresentTime{0}; + std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE}; +}; + + +// Used by the consumer to keep track of which fields it already sent to +// the producer. +class FrameEventDirtyFields { +public: + inline void reset() { mBitset.reset(); } + inline bool anyDirty() const { return mBitset.any(); } + + template <FrameEvent event> + inline void setDirty() { + constexpr size_t eventIndex = static_cast<size_t>(event); + static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index."); + mBitset.set(eventIndex); + } + + template <FrameEvent event> + inline bool isDirty() const { + constexpr size_t eventIndex = static_cast<size_t>(event); + static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index."); + return mBitset[eventIndex]; + } + +private: + std::bitset<FrameEvents::EVENT_COUNT> mBitset; +}; + + +// The consumer's interface to FrameEventHistory +class ConsumerFrameEventHistory : public FrameEventHistory { +public: + ~ConsumerFrameEventHistory() override; + + void onDisconnect(); + + void initializeCompositorTiming(const CompositorTiming& compositorTiming); + + void addQueue(const NewFrameEventsEntry& newEntry); + void addLatch(uint64_t frameNumber, nsecs_t latchTime); + void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime); + void addPostComposition(uint64_t frameNumber, + const std::shared_ptr<FenceTime>& gpuCompositionDone, + const std::shared_ptr<FenceTime>& displayPresent, + const CompositorTiming& compositorTiming); + void addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime, + std::shared_ptr<FenceTime>&& release); + + void getAndResetDelta(FrameEventHistoryDelta* delta); + +private: + void getFrameDelta(FrameEventHistoryDelta* delta, + const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame); + + std::array<FrameEventDirtyFields, MAX_FRAME_HISTORY> mFramesDirty; + + size_t mQueueOffset{0}; + size_t mCompositionOffset{0}; + size_t mReleaseOffset{0}; + + int mCurrentConnectId{0}; + bool mProducerWantsEvents{false}; +}; + + +// A single frame update from the consumer to producer that can be sent +// through Binder. +// Although this may be sent multiple times for the same frame as new +// timestamps are set, Fences only need to be sent once. +class FrameEventsDelta : public Flattenable<FrameEventsDelta> { +friend class ProducerFrameEventHistory; +public: + FrameEventsDelta() = default; + FrameEventsDelta(size_t index, + const FrameEvents& frameTimestamps, + const FrameEventDirtyFields& dirtyFields); + + // Movable. + FrameEventsDelta(FrameEventsDelta&& src) = default; + FrameEventsDelta& operator=(FrameEventsDelta&& src) = default; + // Not copyable. + FrameEventsDelta(const FrameEventsDelta& src) = delete; + FrameEventsDelta& operator=(const FrameEventsDelta& src) = delete; + + // Flattenable implementation + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, + size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, + size_t& count); + +private: + static constexpr size_t minFlattenedSize(); + + size_t mIndex{0}; + uint64_t mFrameNumber{0}; + + bool mAddPostCompositeCalled{0}; + bool mAddReleaseCalled{0}; + + nsecs_t mPostedTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mRequestedPresentTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mLatchTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mFirstRefreshStartTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mLastRefreshStartTime{FrameEvents::TIMESTAMP_PENDING}; + nsecs_t mDequeueReadyTime{FrameEvents::TIMESTAMP_PENDING}; + + FenceTime::Snapshot mGpuCompositionDoneFence; + FenceTime::Snapshot mDisplayPresentFence; + FenceTime::Snapshot mReleaseFence; + + // This is a static method with an auto return value so we can call + // it without needing const and non-const versions. + template <typename ThisT> + static inline auto allFences(ThisT fed) -> + std::array<decltype(&fed->mReleaseFence), 3> { + return {{ + &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence, + &fed->mReleaseFence + }}; + } +}; + + +// A collection of updates from consumer to producer that can be sent +// through Binder. +class FrameEventHistoryDelta + : public Flattenable<FrameEventHistoryDelta> { + +friend class ConsumerFrameEventHistory; +friend class ProducerFrameEventHistory; + +public: + FrameEventHistoryDelta() = default; + + // Movable. + FrameEventHistoryDelta(FrameEventHistoryDelta&& src) = default; + FrameEventHistoryDelta& operator=(FrameEventHistoryDelta&& src); + // Not copyable. + FrameEventHistoryDelta(const FrameEventHistoryDelta& src) = delete; + FrameEventHistoryDelta& operator=( + const FrameEventHistoryDelta& src) = delete; + + // Flattenable implementation. + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, + size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, + size_t& count); + +private: + static constexpr size_t minFlattenedSize(); + + std::vector<FrameEventsDelta> mDeltas; + CompositorTiming mCompositorTiming; +}; + + +} // namespace android +#endif diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h new file mode 100644 index 0000000000..2cf6162fd8 --- /dev/null +++ b/libs/gui/include/gui/GLConsumer.h @@ -0,0 +1,522 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CONSUMER_H +#define ANDROID_GUI_CONSUMER_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <gui/BufferQueueDefs.h> +#include <gui/ConsumerBase.h> + +#include <ui/FenceTime.h> +#include <ui/GraphicBuffer.h> + +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/threads.h> + +namespace android { +// ---------------------------------------------------------------------------- + + +class String8; + +/* + * GLConsumer consumes buffers of graphics data from a BufferQueue, + * and makes them available to OpenGL as a texture. + * + * A typical usage pattern is to set up the GLConsumer with the + * desired options, and call updateTexImage() when a new frame is desired. + * If a new frame is available, the texture will be updated. If not, + * the previous contents are retained. + * + * By default, the texture is attached to the GL_TEXTURE_EXTERNAL_OES + * texture target, in the EGL context of the first thread that calls + * updateTexImage(). + * + * This class was previously called SurfaceTexture. + */ +class GLConsumer : public ConsumerBase { +public: + enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES + typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; + + // GLConsumer constructs a new GLConsumer object. If the constructor with + // the tex parameter is used, tex indicates the name of the OpenGL ES + // texture to which images are to be streamed. texTarget specifies the + // OpenGL ES texture target to which the texture will be bound in + // updateTexImage. useFenceSync specifies whether fences should be used to + // synchronize access to buffers if that behavior is enabled at + // compile-time. + // + // A GLConsumer may be detached from one OpenGL ES context and then + // attached to a different context using the detachFromContext and + // attachToContext methods, respectively. The intention of these methods is + // purely to allow a GLConsumer to be transferred from one consumer + // context to another. If such a transfer is not needed there is no + // requirement that either of these methods be called. + // + // If the constructor with the tex parameter is used, the GLConsumer is + // created in a state where it is considered attached to an OpenGL ES + // context for the purposes of the attachToContext and detachFromContext + // methods. However, despite being considered "attached" to a context, the + // specific OpenGL ES context doesn't get latched until the first call to + // updateTexImage. After that point, all calls to updateTexImage must be + // made with the same OpenGL ES context current. + // + // If the constructor without the tex parameter is used, the GLConsumer is + // created in a detached state, and attachToContext must be called before + // calls to updateTexImage. + GLConsumer(const sp<IGraphicBufferConsumer>& bq, + uint32_t tex, uint32_t texureTarget, bool useFenceSync, + bool isControlledByApp); + + GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texureTarget, + bool useFenceSync, bool isControlledByApp); + + // updateTexImage acquires the most recently queued buffer, and sets the + // image contents of the target texture to it. + // + // This call may only be made while the OpenGL ES context to which the + // target texture belongs is bound to the calling thread. + // + // This calls doGLFenceWait to ensure proper synchronization. + status_t updateTexImage(); + + // releaseTexImage releases the texture acquired in updateTexImage(). + // This is intended to be used in single buffer mode. + // + // This call may only be made while the OpenGL ES context to which the + // target texture belongs is bound to the calling thread. + status_t releaseTexImage(); + + // setReleaseFence stores a fence that will signal when the current buffer + // is no longer being read. This fence will be returned to the producer + // when the current buffer is released by updateTexImage(). Multiple + // fences can be set for a given buffer; they will be merged into a single + // union fence. + virtual void setReleaseFence(const sp<Fence>& fence); + + // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix + // associated with the texture image set by the most recent call to + // updateTexImage. + // + // This transform matrix maps 2D homogeneous texture coordinates of the form + // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture + // coordinate that should be used to sample that location from the texture. + // Sampling the texture outside of the range of this transform is undefined. + // + // This transform is necessary to compensate for transforms that the stream + // content producer may implicitly apply to the content. By forcing users of + // a GLConsumer to apply this transform we avoid performing an extra + // copy of the data that would be needed to hide the transform from the + // user. + // + // The matrix is stored in column-major order so that it may be passed + // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv + // functions. + void getTransformMatrix(float mtx[16]); + + // Computes the transform matrix documented by getTransformMatrix + // from the BufferItem sub parts. + static void computeTransformMatrix(float outTransform[16], + const sp<GraphicBuffer>& buf, const Rect& cropRect, + uint32_t transform, bool filtering); + + // getTimestamp retrieves the timestamp associated with the texture image + // set by the most recent call to updateTexImage. + // + // The timestamp is in nanoseconds, and is monotonically increasing. Its + // other semantics (zero point, etc) are source-dependent and should be + // documented by the source. + int64_t getTimestamp(); + + // getDataSpace retrieves the DataSpace associated with the texture image + // set by the most recent call to updateTexImage. + android_dataspace getCurrentDataSpace(); + + // getFrameNumber retrieves the frame number associated with the texture + // image set by the most recent call to updateTexImage. + // + // The frame number is an incrementing counter set to 0 at the creation of + // the BufferQueue associated with this consumer. + uint64_t getFrameNumber(); + + // setDefaultBufferSize is used to set the size of buffers returned by + // requestBuffers when a with and height of zero is requested. + // A call to setDefaultBufferSize() may trigger requestBuffers() to + // be called from the client. + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. + status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // setFilteringEnabled sets whether the transform matrix should be computed + // for use with bilinear filtering. + void setFilteringEnabled(bool enabled); + + // getCurrentBuffer returns the buffer associated with the current image. + // When outSlot is not nullptr, the current buffer slot index is also + // returned. + sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr) const; + + // getCurrentTextureTarget returns the texture target of the current + // texture as returned by updateTexImage(). + uint32_t getCurrentTextureTarget() const; + + // getCurrentCrop returns the cropping rectangle of the current buffer. + Rect getCurrentCrop() const; + + // getCurrentTransform returns the transform of the current buffer. + uint32_t getCurrentTransform() const; + + // getCurrentScalingMode returns the scaling mode of the current buffer. + uint32_t getCurrentScalingMode() const; + + // getCurrentFence returns the fence indicating when the current buffer is + // ready to be read from. + sp<Fence> getCurrentFence() const; + + // getCurrentFence returns the FenceTime indicating when the current + // buffer is ready to be read from. + std::shared_ptr<FenceTime> getCurrentFenceTime() const; + + // doGLFenceWait inserts a wait command into the OpenGL ES command stream + // to ensure that it is safe for future OpenGL ES commands to access the + // current texture buffer. + status_t doGLFenceWait() const; + + // set the name of the GLConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // These functions call the corresponding BufferQueue implementation + // so the refactoring can proceed smoothly + status_t setDefaultBufferFormat(PixelFormat defaultFormat); + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); + status_t setConsumerUsageBits(uint32_t usage); + status_t setTransformHint(uint32_t hint); + status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); + + // detachFromContext detaches the GLConsumer from the calling thread's + // current OpenGL ES context. This context must be the same as the context + // that was current for previous calls to updateTexImage. + // + // Detaching a GLConsumer from an OpenGL ES context will result in the + // deletion of the OpenGL ES texture object into which the images were being + // streamed. After a GLConsumer has been detached from the OpenGL ES + // context calls to updateTexImage will fail returning INVALID_OPERATION + // until the GLConsumer is attached to a new OpenGL ES context using the + // attachToContext method. + status_t detachFromContext(); + + // attachToContext attaches a GLConsumer that is currently in the + // 'detached' state to the current OpenGL ES context. A GLConsumer is + // in the 'detached' state iff detachFromContext has successfully been + // called and no calls to attachToContext have succeeded since the last + // detachFromContext call. Calls to attachToContext made on a + // GLConsumer that is not in the 'detached' state will result in an + // INVALID_OPERATION error. + // + // The tex argument specifies the OpenGL ES texture object name in the + // new context into which the image contents will be streamed. A successful + // call to attachToContext will result in this texture object being bound to + // the texture target and populated with the image contents that were + // current at the time of the last call to detachFromContext. + status_t attachToContext(uint32_t tex); + +protected: + + // abandonLocked overrides the ConsumerBase method to clear + // mCurrentTextureImage in addition to the ConsumerBase behavior. + virtual void abandonLocked(); + + // dumpLocked overrides the ConsumerBase method to dump GLConsumer- + // specific info in addition to the ConsumerBase behavior. + virtual void dumpLocked(String8& result, const char* prefix) const; + + // acquireBufferLocked overrides the ConsumerBase method to update the + // mEglSlots array in addition to the ConsumerBase behavior. + virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, + uint64_t maxFrameNumber = 0) override; + + // releaseBufferLocked overrides the ConsumerBase method to update the + // mEglSlots array in addition to the ConsumerBase. + virtual status_t releaseBufferLocked(int slot, + const sp<GraphicBuffer> graphicBuffer, + EGLDisplay display, EGLSyncKHR eglFence) override; + + status_t releaseBufferLocked(int slot, + const sp<GraphicBuffer> graphicBuffer, EGLSyncKHR eglFence) { + return releaseBufferLocked(slot, graphicBuffer, mEglDisplay, eglFence); + } + + static bool isExternalFormat(PixelFormat format); + + struct PendingRelease { + PendingRelease() : isPending(false), currentTexture(-1), + graphicBuffer(), display(nullptr), fence(nullptr) {} + + bool isPending; + int currentTexture; + sp<GraphicBuffer> graphicBuffer; + EGLDisplay display; + EGLSyncKHR fence; + }; + + // This releases the buffer in the slot referenced by mCurrentTexture, + // then updates state to refer to the BufferItem, which must be a + // newly-acquired buffer. If pendingRelease is not null, the parameters + // which would have been passed to releaseBufferLocked upon the successful + // completion of the method will instead be returned to the caller, so that + // it may call releaseBufferLocked itself later. + status_t updateAndReleaseLocked(const BufferItem& item, + PendingRelease* pendingRelease = nullptr); + + // Binds mTexName and the current buffer to mTexTarget. Uses + // mCurrentTexture if it's set, mCurrentTextureImage if not. If the + // bind succeeds, this calls doGLFenceWait. + status_t bindTextureImageLocked(); + + // Gets the current EGLDisplay and EGLContext values, and compares them + // to mEglDisplay and mEglContext. If the fields have been previously + // set, the values must match; if not, the fields are set to the current + // values. + // The contextCheck argument is used to ensure that a GL context is + // properly set; when set to false, the check is not performed. + status_t checkAndUpdateEglStateLocked(bool contextCheck = false); + +private: + // EglImage is a utility class for tracking and creating EGLImageKHRs. There + // is primarily just one image per slot, but there is also special cases: + // - For releaseTexImage, we use a debug image (mReleasedTexImage) + // - After freeBuffer, we must still keep the current image/buffer + // Reference counting EGLImages lets us handle all these cases easily while + // also only creating new EGLImages from buffers when required. + class EglImage : public LightRefBase<EglImage> { + public: + EglImage(sp<GraphicBuffer> graphicBuffer); + + // createIfNeeded creates an EGLImage if required (we haven't created + // one yet, or the EGLDisplay or crop-rect has changed). + status_t createIfNeeded(EGLDisplay display, + const Rect& cropRect, + bool forceCreate = false); + + // This calls glEGLImageTargetTexture2DOES to bind the image to the + // texture in the specified texture target. + void bindToTextureTarget(uint32_t texTarget); + + const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; } + const native_handle* graphicBufferHandle() { + return mGraphicBuffer == NULL ? NULL : mGraphicBuffer->handle; + } + + private: + // Only allow instantiation using ref counting. + friend class LightRefBase<EglImage>; + virtual ~EglImage(); + + // createImage creates a new EGLImage from a GraphicBuffer. + EGLImageKHR createImage(EGLDisplay dpy, + const sp<GraphicBuffer>& graphicBuffer, const Rect& crop); + + // Disallow copying + EglImage(const EglImage& rhs); + void operator = (const EglImage& rhs); + + // mGraphicBuffer is the buffer that was used to create this image. + sp<GraphicBuffer> mGraphicBuffer; + + // mEglImage is the EGLImage created from mGraphicBuffer. + EGLImageKHR mEglImage; + + // mEGLDisplay is the EGLDisplay that was used to create mEglImage. + EGLDisplay mEglDisplay; + + // mCropRect is the crop rectangle passed to EGL when mEglImage + // was created. + Rect mCropRect; + }; + + // freeBufferLocked frees up the given buffer slot. If the slot has been + // initialized this will release the reference to the GraphicBuffer in that + // slot and destroy the EGLImage in that slot. Otherwise it has no effect. + // + // This method must be called with mMutex locked. + virtual void freeBufferLocked(int slotIndex); + + // computeCurrentTransformMatrixLocked computes the transform matrix for the + // current texture. It uses mCurrentTransform and the current GraphicBuffer + // to compute this matrix and stores it in mCurrentTransformMatrix. + // mCurrentTextureImage must not be NULL. + void computeCurrentTransformMatrixLocked(); + + // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command + // stream to ensure that it is safe for future OpenGL ES commands to + // access the current texture buffer. + status_t doGLFenceWaitLocked() const; + + // syncForReleaseLocked performs the synchronization needed to release the + // current slot from an OpenGL ES context. If needed it will set the + // current slot's fence to guard against a producer accessing the buffer + // before the outstanding accesses have completed. + status_t syncForReleaseLocked(EGLDisplay dpy); + + // returns a graphic buffer used when the texture image has been released + static sp<GraphicBuffer> getDebugTexImageBuffer(); + + // The default consumer usage flags that GLConsumer always sets on its + // BufferQueue instance; these will be OR:d with any additional flags passed + // from the GLConsumer user. In particular, GLConsumer will always + // consume buffers as hardware textures. + static const uint32_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; + + // mCurrentTextureImage is the EglImage/buffer of the current texture. It's + // possible that this buffer is not associated with any buffer slot, so we + // must track it separately in order to support the getCurrentBuffer method. + sp<EglImage> mCurrentTextureImage; + + // mCurrentCrop is the crop rectangle that applies to the current texture. + // It gets set each time updateTexImage is called. + Rect mCurrentCrop; + + // mCurrentTransform is the transform identifier for the current texture. It + // gets set each time updateTexImage is called. + uint32_t mCurrentTransform; + + // mCurrentScalingMode is the scaling mode for the current texture. It gets + // set each time updateTexImage is called. + uint32_t mCurrentScalingMode; + + // mCurrentFence is the fence received from BufferQueue in updateTexImage. + sp<Fence> mCurrentFence; + + // The FenceTime wrapper around mCurrentFence. + std::shared_ptr<FenceTime> mCurrentFenceTime{FenceTime::NO_FENCE}; + + // mCurrentTransformMatrix is the transform matrix for the current texture. + // It gets computed by computeTransformMatrix each time updateTexImage is + // called. + float mCurrentTransformMatrix[16]; + + // mCurrentTimestamp is the timestamp for the current texture. It + // gets set each time updateTexImage is called. + int64_t mCurrentTimestamp; + + // mCurrentDataSpace is the dataspace for the current texture. It + // gets set each time updateTexImage is called. + android_dataspace mCurrentDataSpace; + + // mCurrentFrameNumber is the frame counter for the current texture. + // It gets set each time updateTexImage is called. + uint64_t mCurrentFrameNumber; + + uint32_t mDefaultWidth, mDefaultHeight; + + // mFilteringEnabled indicates whether the transform matrix is computed for + // use with bilinear filtering. It defaults to true and is changed by + // setFilteringEnabled(). + bool mFilteringEnabled; + + // mTexName is the name of the OpenGL texture to which streamed images will + // be bound when updateTexImage is called. It is set at construction time + // and can be changed with a call to attachToContext. + uint32_t mTexName; + + // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync + // extension should be used to prevent buffers from being dequeued before + // it's safe for them to be written. It gets set at construction time and + // never changes. + const bool mUseFenceSync; + + // mTexTarget is the GL texture target with which the GL texture object is + // associated. It is set in the constructor and never changed. It is + // almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android + // Browser. In that case it is set to GL_TEXTURE_2D to allow + // glCopyTexSubImage to read from the texture. This is a hack to work + // around a GL driver limitation on the number of FBO attachments, which the + // browser's tile cache exceeds. + const uint32_t mTexTarget; + + // EGLSlot contains the information and object references that + // GLConsumer maintains about a BufferQueue buffer slot. + struct EglSlot { + EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {} + + // mEglImage is the EGLImage created from mGraphicBuffer. + sp<EglImage> mEglImage; + + // mFence is the EGL sync object that must signal before the buffer + // associated with this buffer slot may be dequeued. It is initialized + // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based + // on a compile-time option) set to a new sync object in updateTexImage. + EGLSyncKHR mEglFence; + }; + + // mEglDisplay is the EGLDisplay with which this GLConsumer is currently + // associated. It is intialized to EGL_NO_DISPLAY and gets set to the + // current display when updateTexImage is called for the first time and when + // attachToContext is called. + EGLDisplay mEglDisplay; + + // mEglContext is the OpenGL ES context with which this GLConsumer is + // currently associated. It is initialized to EGL_NO_CONTEXT and gets set + // to the current GL context when updateTexImage is called for the first + // time and when attachToContext is called. + EGLContext mEglContext; + + // mEGLSlots stores the buffers that have been allocated by the BufferQueue + // for each buffer slot. It is initialized to null pointers, and gets + // filled in with the result of BufferQueue::acquire when the + // client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + EglSlot mEglSlots[BufferQueueDefs::NUM_BUFFER_SLOTS]; + + // mCurrentTexture is the buffer slot index of the buffer that is currently + // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT, + // indicating that no buffer slot is currently bound to the texture. Note, + // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean + // that no buffer is bound to the texture. A call to setBufferCount will + // reset mCurrentTexture to INVALID_BUFFER_SLOT. + int mCurrentTexture; + + // mAttached indicates whether the ConsumerBase is currently attached to + // an OpenGL ES context. For legacy reasons, this is initialized to true, + // indicating that the ConsumerBase is considered to be attached to + // whatever context is current at the time of the first updateTexImage call. + // It is set to false by detachFromContext, and then set to true again by + // attachToContext. + bool mAttached; + + // protects static initialization + static Mutex sStaticInitLock; + + // mReleasedTexImageBuffer is a dummy buffer used when in single buffer + // mode and releaseTexImage() has been called + static sp<GraphicBuffer> sReleasedTexImageBuffer; + sp<EglImage> mReleasedTexImage; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_CONSUMER_H diff --git a/libs/gui/include/gui/GuiConfig.h b/libs/gui/include/gui/GuiConfig.h new file mode 100644 index 0000000000..b020ed9b6a --- /dev/null +++ b/libs/gui/include/gui/GuiConfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CONFIG_H +#define ANDROID_GUI_CONFIG_H + +#include <utils/String8.h> + +namespace android { + +// Append the libgui configuration details to configStr. +void appendGuiConfigString(String8& configStr); + +}; // namespace android + +#endif /*ANDROID_GUI_CONFIG_H*/ diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h new file mode 100644 index 0000000000..c0828820e3 --- /dev/null +++ b/libs/gui/include/gui/IConsumerListener.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <binder/IInterface.h> +#include <binder/SafeInterface.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> + +#include <cstdint> + +namespace android { + +class BufferItem; +class FrameEventHistoryDelta; +struct NewFrameEventsEntry; + +// ConsumerListener is the interface through which the BufferQueue notifies the consumer of events +// that the consumer may wish to react to. Because the consumer will generally have a mutex that is +// locked during calls from the consumer to the BufferQueue, these calls from the BufferQueue to the +// consumer *MUST* be called only when the BufferQueue mutex is NOT locked. + +class ConsumerListener : public virtual RefBase { +public: + ConsumerListener() {} + virtual ~ConsumerListener(); + + // onDisconnect is called when a producer disconnects from the BufferQueue. + virtual void onDisconnect() {} /* Asynchronous */ + + // onFrameAvailable is called from queueBuffer each time an additional frame becomes available + // for consumption. This means that frames that are queued while in asynchronous mode only + // trigger the callback if no previous frames are pending. Frames queued while in synchronous + // mode always trigger the callback. The item passed to the callback will contain all of the + // information about the queued frame except for its GraphicBuffer pointer, which will always be + // null (except if the consumer is SurfaceFlinger). + // + // This is called without any lock held and can be called concurrently by multiple threads. + virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */ + + // onFrameReplaced is called from queueBuffer if the frame being queued is replacing an existing + // slot in the queue. Any call to queueBuffer that doesn't call onFrameAvailable will call this + // callback instead. The item passed to the callback will contain all of the information about + // the queued frame except for its GraphicBuffer pointer, which will always be null. + // + // This is called without any lock held and can be called concurrently by multiple threads. + virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */ + + // onBuffersReleased is called to notify the buffer consumer that the BufferQueue has released + // its references to one or more GraphicBuffers contained in its slots. The buffer consumer + // should then call BufferQueue::getReleasedBuffers to retrieve the list of buffers. + // + // This is called without any lock held and can be called concurrently by multiple threads. + virtual void onBuffersReleased() = 0; /* Asynchronous */ + + // onSidebandStreamChanged is called to notify the buffer consumer that the BufferQueue's + // sideband buffer stream has changed. This is called when a stream is first attached and when + // it is either detached or replaced by a different stream. + virtual void onSidebandStreamChanged() = 0; /* Asynchronous */ + + // Notifies the consumer of any new producer-side timestamps and returns the combined frame + // history that hasn't already been retrieved. + // + // WARNING: This method can only be called when the BufferQueue is in the consumer's process. + virtual void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/, + FrameEventHistoryDelta* /*outDelta*/) {} +}; + +class IConsumerListener : public ConsumerListener, public IInterface { +public: + DECLARE_META_INTERFACE(ConsumerListener) +}; + +class BnConsumerListener : public SafeBnInterface<IConsumerListener> { +public: + BnConsumerListener() : SafeBnInterface<IConsumerListener>("BnConsumerListener") {} + + status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags = 0) override; +}; + +} // namespace android diff --git a/libs/gui/include/gui/IDisplayEventConnection.h b/libs/gui/include/gui/IDisplayEventConnection.h new file mode 100644 index 0000000000..d783f74d7c --- /dev/null +++ b/libs/gui/include/gui/IDisplayEventConnection.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <binder/IInterface.h> +#include <binder/SafeInterface.h> + +#include <utils/Errors.h> + +#include <cstdint> + +namespace android { + +namespace gui { +class BitTube; +} // namespace gui + +class IDisplayEventConnection : public IInterface { +public: + DECLARE_META_INTERFACE(DisplayEventConnection) + + /* + * stealReceiveChannel() returns a BitTube to receive events from. Only the receive file + * descriptor of outChannel will be initialized, and this effectively "steals" the receive + * channel from the remote end (such that the remote end can only use its send channel). + */ + virtual status_t stealReceiveChannel(gui::BitTube* outChannel) = 0; + + /* + * setVsyncRate() sets the vsync event delivery rate. A value of 1 returns every vsync event. + * A value of 2 returns every other event, etc. A value of 0 returns no event unless + * requestNextVsync() has been called. + */ + virtual status_t setVsyncRate(uint32_t count) = 0; + + /* + * requestNextVsync() schedules the next vsync event. It has no effect if the vsync rate is > 0. + */ + virtual void requestNextVsync() = 0; // Asynchronous +}; + +class BnDisplayEventConnection : public SafeBnInterface<IDisplayEventConnection> { +public: + BnDisplayEventConnection() + : SafeBnInterface<IDisplayEventConnection>("BnDisplayEventConnection") {} + + status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags = 0) override; +}; + +} // namespace android diff --git a/libs/gui/include/gui/IGraphicBufferConsumer.h b/libs/gui/include/gui/IGraphicBufferConsumer.h new file mode 100644 index 0000000000..3d069dfe48 --- /dev/null +++ b/libs/gui/include/gui/IGraphicBufferConsumer.h @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <gui/OccupancyTracker.h> + +#include <binder/IInterface.h> +#include <binder/SafeInterface.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <ui/PixelFormat.h> + +#include <utils/Errors.h> + +namespace android { + +class BufferItem; +class Fence; +class GraphicBuffer; +class IConsumerListener; +class NativeHandle; + +class IGraphicBufferConsumer : public IInterface { +public: + DECLARE_META_INTERFACE(GraphicBufferConsumer) + + enum { + // Returned by releaseBuffer, after which the consumer must free any references to the + // just-released buffer that it might have. + STALE_BUFFER_SLOT = 1, + // Returned by dequeueBuffer if there are no pending buffers available. + NO_BUFFER_AVAILABLE, + // Returned by dequeueBuffer if it's too early for the buffer to be acquired. + PRESENT_LATER, + }; + + // acquireBuffer attempts to acquire ownership of the next pending buffer in the BufferQueue. + // If no buffer is pending then it returns NO_BUFFER_AVAILABLE. If a buffer is successfully + // acquired, the information about the buffer is returned in BufferItem. + // + // If the buffer returned had previously been acquired then the BufferItem::mGraphicBuffer field + // of buffer is set to NULL and it is assumed that the consumer still holds a reference to the + // buffer. + // + // If presentWhen is non-zero, it indicates the time when the buffer will be displayed on + // screen. If the buffer's timestamp is farther in the future, the buffer won't be acquired, and + // PRESENT_LATER will be returned. The presentation time is in nanoseconds, and the time base + // is CLOCK_MONOTONIC. + // + // If maxFrameNumber is non-zero, it indicates that acquireBuffer should only return a buffer + // with a frame number less than or equal to maxFrameNumber. If no such frame is available + // (such as when a buffer has been replaced but the consumer has not received the + // onFrameReplaced callback), then PRESENT_LATER will be returned. + // + // Return of NO_ERROR means the operation completed as normal. + // + // Return of a positive value means the operation could not be completed at this time, but the + // user should try again later: + // * NO_BUFFER_AVAILABLE - no buffer is pending (nothing queued by producer) + // * PRESENT_LATER - the buffer's timestamp is farther in the future + // + // Return of a negative value means an error has occurred: + // * INVALID_OPERATION - too many buffers have been acquired + virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen, + uint64_t maxFrameNumber = 0) = 0; + + // detachBuffer attempts to remove all ownership of the buffer in the given slot from the buffer + // queue. If this call succeeds, the slot will be freed, and there will be no way to obtain the + // buffer from this interface. The freed slot will remain unallocated until either it is + // selected to hold a freshly allocated buffer in dequeueBuffer or a buffer is attached to the + // slot. The buffer must have already been acquired. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - the given slot number is invalid, either because it is out of the range + // [0, NUM_BUFFER_SLOTS) or because the slot it refers to is not + // currently acquired. + virtual status_t detachBuffer(int slot) = 0; + + // attachBuffer attempts to transfer ownership of a buffer to the BufferQueue. If this call + // succeeds, it will be as if this buffer was acquired from the returned slot number. As such, + // this call will fail if attaching this buffer would cause too many buffers to be + // simultaneously acquired. + // + // If the buffer is successfully attached, its frameNumber is initialized to 0. This must be + // passed into the releaseBuffer call or else the buffer will be deallocated as stale. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - outSlot or buffer were NULL, or the generation number of the buffer did not + // match the BufferQueue. + // * INVALID_OPERATION - cannot attach the buffer because it would cause too many buffers + // to be acquired. + // * NO_MEMORY - no free slots available + virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) = 0; + + // releaseBuffer releases a buffer slot from the consumer back to the BufferQueue. This may be + // done while the buffer's contents are still being accessed. The fence will signal when the + // buffer is no longer in use. frameNumber is used to identify the exact buffer returned. + // + // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free any references to the + // just-released buffer that it might have, as if it had received a onBuffersReleased() call + // with a mask set for the released buffer. + // + // Note that the dependencies on EGL will be removed once we switch to using the Android HW + // Sync HAL. + // + // Return of NO_ERROR means the operation completed as normal. + // + // Return of a positive value means the operation could not be completed at this time, but the + // user should try again later: + // * STALE_BUFFER_SLOT - see above (second paragraph) + // + // Return of a negative value means an error has occurred: + // * BAD_VALUE - one of the following could've happened: + // * the buffer slot was invalid + // * the fence was NULL + // * the buffer slot specified is not in the acquired state + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, + EGLSyncKHR fence, const sp<Fence>& releaseFence) = 0; + + status_t releaseHelper(int buf, uint64_t frameNumber, const sp<Fence>& releaseFence) { + return releaseBuffer(buf, frameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence); + } + // This is explicitly *not* the actual signature of IGBC::releaseBuffer, but: + // 1) We have no easy way to send the EGL objects across Binder + // 2) This has always been broken, probably because + // 3) IGBC is rarely remoted + // For now, we will choose to bury our heads in the sand and ignore this problem until such time + // as we can finally finish converting away from EGL sync to native Android sync + using ReleaseBuffer = decltype(&IGraphicBufferConsumer::releaseHelper); + + // consumerConnect connects a consumer to the BufferQueue. Only one consumer may be connected, + // and when that consumer disconnects the BufferQueue is placed into the "abandoned" state, + // causing most interactions with the BufferQueue by the producer to fail. controlledByApp + // indicates whether the consumer is controlled by the application. + // + // consumer may not be NULL. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the BufferQueue has been abandoned + // * BAD_VALUE - a NULL consumer was provided + virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, + bool controlledByApp) = 0; + + // consumerDisconnect disconnects a consumer from the BufferQueue. All buffers will be freed and + // the BufferQueue is placed in the "abandoned" state, causing most interactions with the + // BufferQueue by the producer to fail. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - no consumer is currently connected + virtual status_t consumerDisconnect() = 0; + + // getReleasedBuffers sets the value pointed to by slotMask to a bit set. Each bit index with a + // 1 corresponds to a released buffer slot with that index value. In particular, a released + // buffer is one that has been released by the BufferQueue but has not yet been released by + // the consumer. + // + // This should be called from the onBuffersReleased() callback. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the BufferQueue has been abandoned. + virtual status_t getReleasedBuffers(uint64_t* slotMask) = 0; + + // setDefaultBufferSize is used to set the size of buffers returned by dequeueBuffer when a + // width and height of zero is requested. Default is 1x1. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - either w or h was zero + virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) = 0; + + // setMaxBufferCount sets the maximum value for the number of buffers used in the BufferQueue + // (the initial default is NUM_BUFFER_SLOTS). If a call to setMaxAcquiredBufferCount (by the + // consumer), or a call to setAsyncMode or setMaxDequeuedBufferCount (by the producer), would + // cause this value to be exceeded then that call will fail. This call will fail if a producer + // is connected to the BufferQueue. + // + // The count must be between 1 and NUM_BUFFER_SLOTS, inclusive. The count cannot be less than + // maxAcquiredBufferCount. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - one of the below conditions occurred: + // * bufferCount was out of range (see above). + // * failure to adjust the number of available slots. + // * INVALID_OPERATION - attempting to call this after a producer connected. + virtual status_t setMaxBufferCount(int bufferCount) = 0; + + // setMaxAcquiredBufferCount sets the maximum number of buffers that can be acquired by the + // consumer at one time (default 1). If this method succeeds, any new buffer slots will be both + // unallocated and owned by the BufferQueue object (i.e. they are not owned by the producer or + // consumer). Calling this may also cause some buffer slots to be emptied. + // + // This function should not be called with a value of maxAcquiredBuffers that is less than the + // number of currently acquired buffer slots. Doing so will result in a BAD_VALUE error. + // + // maxAcquiredBuffers must be (inclusive) between 1 and MAX_MAX_ACQUIRED_BUFFERS. It also cannot + // cause the maxBufferCount value to be exceeded. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the BufferQueue has been abandoned + // * BAD_VALUE - one of the below conditions occurred: + // * maxAcquiredBuffers was out of range (see above). + // * failure to adjust the number of available slots. + // * client would have more than the requested number of acquired buffers after + // this call + // * INVALID_OPERATION - attempting to call this after a producer connected. + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0; + + // setConsumerName sets the name used in logging + virtual status_t setConsumerName(const String8& name) = 0; + + // setDefaultBufferFormat allows the BufferQueue to create GraphicBuffers of a defaultFormat if + // no format is specified in dequeueBuffer. The initial default is PIXEL_FORMAT_RGBA_8888. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) = 0; + + // setDefaultBufferDataSpace is a request to the producer to provide buffers of the indicated + // dataSpace. The producer may ignore this request. The initial default is + // HAL_DATASPACE_UNKNOWN. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) = 0; + + // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer. These are merged + // with the bits passed to dequeueBuffer. The values are enumerated in gralloc.h, + // e.g. GRALLOC_USAGE_HW_RENDER; the default is 0. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setConsumerUsageBits(uint32_t usage) = 0; + + // setConsumerIsProtected will turn on an internal bit that indicates whether + // the consumer can handle protected gralloc buffers (i.e. with + // GRALLOC_USAGE_PROTECTED set). IGraphicBufferProducer can query this + // capability using NATIVE_WINDOW_CONSUMER_IS_PROTECTED. + virtual status_t setConsumerIsProtected(bool isProtected) = 0; + + // setTransformHint bakes in rotation to buffers so overlays can be used. The values are + // enumerated in window.h, e.g. NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 + // (no transform). + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setTransformHint(uint32_t hint) = 0; + + // Retrieve the sideband buffer stream, if any. + virtual status_t getSidebandStream(sp<NativeHandle>* outStream) const = 0; + + // Retrieves any stored segments of the occupancy history of this BufferQueue and clears them. + // Optionally closes out the pending segment if forceFlush is true. + virtual status_t getOccupancyHistory(bool forceFlush, + std::vector<OccupancyTracker::Segment>* outHistory) = 0; + + // discardFreeBuffers releases all currently-free buffers held by the BufferQueue, in order to + // reduce the memory consumption of the BufferQueue to the minimum possible without + // discarding data. + // The consumer invoking this method is responsible for calling getReleasedBuffers() after this + // call to free up any of its locally cached buffers. + virtual status_t discardFreeBuffers() = 0; + + // dump state into a string + virtual status_t dumpState(const String8& prefix, String8* outResult) const = 0; + + // Provide backwards source compatibility + void dumpState(String8& result, const char* prefix) { + String8 returned; + dumpState(String8(prefix), &returned); + result.append(returned); + } +}; + +class BnGraphicBufferConsumer : public SafeBnInterface<IGraphicBufferConsumer> { +public: + BnGraphicBufferConsumer() + : SafeBnInterface<IGraphicBufferConsumer>("BnGraphicBufferConsumer") {} + + status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags = 0) override; +}; + +} // namespace android diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h new file mode 100644 index 0000000000..925080663e --- /dev/null +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -0,0 +1,612 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H +#define ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> +#include <utils/RefBase.h> + +#include <binder/IInterface.h> + +#include <ui/Fence.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> +#include <ui/Region.h> + +#include <gui/FrameTimestamps.h> + +#include <hidl/HybridInterface.h> +#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h> + +namespace android { +// ---------------------------------------------------------------------------- + +class IProducerListener; +class NativeHandle; +class Surface; +typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer + HGraphicBufferProducer; + +/* + * This class defines the Binder IPC interface for the producer side of + * a queue of graphics buffers. It's used to send graphics data from one + * component to another. For example, a class that decodes video for + * playback might use this to provide frames. This is typically done + * indirectly, through Surface. + * + * The underlying mechanism is a BufferQueue, which implements + * BnGraphicBufferProducer. In normal operation, the producer calls + * dequeueBuffer() to get an empty buffer, fills it with data, then + * calls queueBuffer() to make it available to the consumer. + * + * This class was previously called ISurfaceTexture. + */ +class IGraphicBufferProducer : public IInterface +{ +public: + DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, HGraphicBufferProducer) + + enum { + // A flag returned by dequeueBuffer when the client needs to call + // requestBuffer immediately thereafter. + BUFFER_NEEDS_REALLOCATION = 0x1, + // A flag returned by dequeueBuffer when all mirrored slots should be + // released by the client. This flag should always be processed first. + RELEASE_ALL_BUFFERS = 0x2, + }; + + // requestBuffer requests a new buffer for the given index. The server (i.e. + // the IGraphicBufferProducer implementation) assigns the newly created + // buffer to the given slot index, and the client is expected to mirror the + // slot->buffer mapping so that it's not necessary to transfer a + // GraphicBuffer for every dequeue operation. + // + // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - one of the two conditions occurred: + // * slot was out of range (see above) + // * buffer specified by the slot is not dequeued + virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0; + + // setMaxDequeuedBufferCount sets the maximum number of buffers that can be + // dequeued by the producer at one time. If this method succeeds, any new + // buffer slots will be both unallocated and owned by the BufferQueue object + // (i.e. they are not owned by the producer or consumer). Calling this may + // also cause some buffer slots to be emptied. If the caller is caching the + // contents of the buffer slots, it should empty that cache after calling + // this method. + // + // This function should not be called with a value of maxDequeuedBuffers + // that is less than the number of currently dequeued buffer slots. Doing so + // will result in a BAD_VALUE error. + // + // The buffer count should be at least 1 (inclusive), but at most + // (NUM_BUFFER_SLOTS - the minimum undequeued buffer count) (exclusive). The + // minimum undequeued buffer count can be obtained by calling + // query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - one of the below conditions occurred: + // * bufferCount was out of range (see above). + // * client would have more than the requested number of dequeued + // buffers after this call. + // * this call would cause the maxBufferCount value to be exceeded. + // * failure to adjust the number of available slots. + virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) = 0; + + // Set the async flag if the producer intends to asynchronously queue + // buffers without blocking. Typically this is used for triple-buffering + // and/or when the swap interval is set to zero. + // + // Enabling async mode will internally allocate an additional buffer to + // allow for the asynchronous behavior. If it is not enabled queue/dequeue + // calls may block. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - one of the following has occurred: + // * this call would cause the maxBufferCount value to be + // exceeded + // * failure to adjust the number of available slots. + virtual status_t setAsyncMode(bool async) = 0; + + // dequeueBuffer requests a new buffer slot for the client to use. Ownership + // of the slot is transfered to the client, meaning that the server will not + // use the contents of the buffer associated with that slot. + // + // The slot index returned may or may not contain a buffer (client-side). + // If the slot is empty the client should call requestBuffer to assign a new + // buffer to that slot. + // + // Once the client is done filling this buffer, it is expected to transfer + // buffer ownership back to the server with either cancelBuffer on + // the dequeued slot or to fill in the contents of its associated buffer + // contents and call queueBuffer. + // + // If dequeueBuffer returns the BUFFER_NEEDS_REALLOCATION flag, the client is + // expected to call requestBuffer immediately. + // + // If dequeueBuffer returns the RELEASE_ALL_BUFFERS flag, the client is + // expected to release all of the mirrored slot->buffer mappings. + // + // The fence parameter will be updated to hold the fence associated with + // the buffer. The contents of the buffer must not be overwritten until the + // fence signals. If the fence is Fence::NO_FENCE, the buffer may be written + // immediately. + // + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. If width and height are both zero, the + // default values specified by setDefaultBufferSize() are used instead. + // + // If the format is 0, the default format will be used. + // + // The usage argument specifies gralloc buffer usage flags. The values + // are enumerated in <gralloc.h>, e.g. GRALLOC_USAGE_HW_RENDER. These + // will be merged with the usage flags specified by + // IGraphicBufferConsumer::setConsumerUsageBits. + // + // This call will block until a buffer is available to be dequeued. If + // both the producer and consumer are controlled by the app, then this call + // can never block and will return WOULD_BLOCK if no buffer is available. + // + // A non-negative value with flags set (see above) will be returned upon + // success. + // + // Return of a negative means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - both in async mode and buffer count was less than the + // max numbers of buffers that can be allocated at once. + // * INVALID_OPERATION - cannot attach the buffer because it would cause + // too many buffers to be dequeued, either because + // the producer already has a single buffer dequeued + // and did not set a buffer count, or because a + // buffer count was set and this call would cause + // it to be exceeded. + // * WOULD_BLOCK - no buffer is currently available, and blocking is disabled + // since both the producer/consumer are controlled by app + // * NO_MEMORY - out of memory, cannot allocate the graphics buffer. + // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while + // waiting for a buffer to become available. + // + // All other negative values are an unknown error returned downstream + // from the graphics allocator (typically errno). + virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w, + uint32_t h, PixelFormat format, uint32_t usage, + FrameEventHistoryDelta* outTimestamps) = 0; + + // detachBuffer attempts to remove all ownership of the buffer in the given + // slot from the buffer queue. If this call succeeds, the slot will be + // freed, and there will be no way to obtain the buffer from this interface. + // The freed slot will remain unallocated until either it is selected to + // hold a freshly allocated buffer in dequeueBuffer or a buffer is attached + // to the slot. The buffer must have already been dequeued, and the caller + // must already possesses the sp<GraphicBuffer> (i.e., must have called + // requestBuffer). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - the given slot number is invalid, either because it is + // out of the range [0, NUM_BUFFER_SLOTS), or because the slot + // it refers to is not currently dequeued and requested. + virtual status_t detachBuffer(int slot) = 0; + + // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, + // and detachBuffer in sequence, except for two things: + // + // 1) It is unnecessary to know the dimensions, format, or usage of the + // next buffer. + // 2) It will not block, since if it cannot find an appropriate buffer to + // return, it will return an error instead. + // + // Only slots that are free but still contain a GraphicBuffer will be + // considered, and the oldest of those will be returned. outBuffer is + // equivalent to outBuffer from the requestBuffer call, and outFence is + // equivalent to fence from the dequeueBuffer call. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - either outBuffer or outFence were NULL. + // * NO_MEMORY - no slots were found that were both free and contained a + // GraphicBuffer. + virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence) = 0; + + // attachBuffer attempts to transfer ownership of a buffer to the buffer + // queue. If this call succeeds, it will be as if this buffer was dequeued + // from the returned slot number. As such, this call will fail if attaching + // this buffer would cause too many buffers to be simultaneously dequeued. + // + // If attachBuffer returns the RELEASE_ALL_BUFFERS flag, the caller is + // expected to release all of the mirrored slot->buffer mappings. + // + // A non-negative value with flags set (see above) will be returned upon + // success. + // + // Return of a negative value means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - outSlot or buffer were NULL, invalid combination of + // async mode and buffer count override, or the generation + // number of the buffer did not match the buffer queue. + // * INVALID_OPERATION - cannot attach the buffer because it would cause + // too many buffers to be dequeued, either because + // the producer already has a single buffer dequeued + // and did not set a buffer count, or because a + // buffer count was set and this call would cause + // it to be exceeded. + // * WOULD_BLOCK - no buffer slot is currently available, and blocking is + // disabled since both the producer/consumer are + // controlled by the app. + // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while + // waiting for a slot to become available. + virtual status_t attachBuffer(int* outSlot, + const sp<GraphicBuffer>& buffer) = 0; + + // queueBuffer indicates that the client has finished filling in the + // contents of the buffer associated with slot and transfers ownership of + // that slot back to the server. + // + // It is not valid to call queueBuffer on a slot that is not owned + // by the client or one for which a buffer associated via requestBuffer + // (an attempt to do so will fail with a return value of BAD_VALUE). + // + // In addition, the input must be described by the client (as documented + // below). Any other properties (zero point, etc) + // are client-dependent, and should be documented by the client. + // + // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // + // Upon success, the output will be filled with meaningful values + // (refer to the documentation below). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - one of the below conditions occurred: + // * fence was NULL + // * scaling mode was unknown + // * both in async mode and buffer count was less than the + // max numbers of buffers that can be allocated at once + // * slot index was out of range (see above). + // * the slot was not in the dequeued state + // * the slot was enqueued without requesting a buffer + // * crop rect is out of bounds of the buffer dimensions + + struct QueueBufferInput : public Flattenable<QueueBufferInput> { + friend class Flattenable<QueueBufferInput>; + explicit inline QueueBufferInput(const Parcel& parcel); + + // timestamp - a monotonically increasing value in nanoseconds + // isAutoTimestamp - if the timestamp was synthesized at queue time + // dataSpace - description of the contents, interpretation depends on format + // crop - a crop rectangle that's used as a hint to the consumer + // scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in <window.h> + // transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in <window.h> + // fence - a fence that the consumer must wait on before reading the buffer, + // set this to Fence::NO_FENCE if the buffer is ready immediately + // sticky - the sticky transform set in Surface (only used by the LEGACY + // camera mode). + // getFrameTimestamps - whether or not the latest frame timestamps + // should be retrieved from the consumer. + inline QueueBufferInput(int64_t _timestamp, bool _isAutoTimestamp, + android_dataspace _dataSpace, const Rect& _crop, + int _scalingMode, uint32_t _transform, const sp<Fence>& _fence, + uint32_t _sticky = 0, bool _getFrameTimestamps = false) + : timestamp(_timestamp), isAutoTimestamp(_isAutoTimestamp), + dataSpace(_dataSpace), crop(_crop), scalingMode(_scalingMode), + transform(_transform), stickyTransform(_sticky), fence(_fence), + surfaceDamage(), getFrameTimestamps(_getFrameTimestamps) { } + + inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp, + android_dataspace* outDataSpace, + Rect* outCrop, int* outScalingMode, + uint32_t* outTransform, sp<Fence>* outFence, + uint32_t* outStickyTransform = nullptr, + bool* outGetFrameTimestamps = nullptr) const { + *outTimestamp = timestamp; + *outIsAutoTimestamp = bool(isAutoTimestamp); + *outDataSpace = dataSpace; + *outCrop = crop; + *outScalingMode = scalingMode; + *outTransform = transform; + *outFence = fence; + if (outStickyTransform != NULL) { + *outStickyTransform = stickyTransform; + } + if (outGetFrameTimestamps) { + *outGetFrameTimestamps = getFrameTimestamps; + } + } + + // Flattenable protocol + static constexpr size_t minFlattenedSize(); + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + + const Region& getSurfaceDamage() const { return surfaceDamage; } + void setSurfaceDamage(const Region& damage) { surfaceDamage = damage; } + + private: + int64_t timestamp{0}; + int isAutoTimestamp{0}; + android_dataspace dataSpace{HAL_DATASPACE_UNKNOWN}; + Rect crop; + int scalingMode{0}; + uint32_t transform{0}; + uint32_t stickyTransform{0}; + sp<Fence> fence; + Region surfaceDamage; + bool getFrameTimestamps{false}; + }; + + struct QueueBufferOutput : public Flattenable<QueueBufferOutput> { + QueueBufferOutput() = default; + + // Moveable. + QueueBufferOutput(QueueBufferOutput&& src) = default; + QueueBufferOutput& operator=(QueueBufferOutput&& src) = default; + // Not copyable. + QueueBufferOutput(const QueueBufferOutput& src) = delete; + QueueBufferOutput& operator=(const QueueBufferOutput& src) = delete; + + // Flattenable protocol + static constexpr size_t minFlattenedSize(); + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + + uint32_t width{0}; + uint32_t height{0}; + uint32_t transformHint{0}; + uint32_t numPendingBuffers{0}; + uint64_t nextFrameNumber{0}; + FrameEventHistoryDelta frameTimestamps; + bool bufferReplaced{false}; + }; + + virtual status_t queueBuffer(int slot, const QueueBufferInput& input, + QueueBufferOutput* output) = 0; + + // cancelBuffer indicates that the client does not wish to fill in the + // buffer associated with slot and transfers ownership of the slot back to + // the server. + // + // The buffer is not queued for use by the consumer. + // + // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // + // The buffer will not be overwritten until the fence signals. The fence + // will usually be the one obtained from dequeueBuffer. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned or the producer is not + // connected. + // * BAD_VALUE - one of the below conditions occurred: + // * fence was NULL + // * slot index was out of range (see above). + // * the slot was not in the dequeued state + virtual status_t cancelBuffer(int slot, const sp<Fence>& fence) = 0; + + // query retrieves some information for this surface + // 'what' tokens allowed are that of NATIVE_WINDOW_* in <window.h> + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - what was out of range + virtual int query(int what, int* value) = 0; + + // connect attempts to connect a client API to the IGraphicBufferProducer. + // This must be called before any other IGraphicBufferProducer methods are + // called except for getAllocator. A consumer must be already connected. + // + // This method will fail if the connect was previously called on the + // IGraphicBufferProducer and no corresponding disconnect call was made. + // + // The listener is an optional binder callback object that can be used if + // the producer wants to be notified when the consumer releases a buffer + // back to the BufferQueue. It is also used to detect the death of the + // producer. If only the latter functionality is desired, there is a + // DummyProducerListener class in IProducerListener.h that can be used. + // + // The api should be one of the NATIVE_WINDOW_API_* values in <window.h> + // + // The producerControlledByApp should be set to true if the producer is hosted + // by an untrusted process (typically app_process-forked processes). If both + // the producer and the consumer are app-controlled then all buffer queues + // will operate in async mode regardless of the async flag. + // + // Upon success, the output will be filled with meaningful data + // (refer to QueueBufferOutput documentation above). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - one of the following occurred: + // * the buffer queue was abandoned + // * no consumer has yet connected + // * BAD_VALUE - one of the following has occurred: + // * the producer is already connected + // * api was out of range (see above). + // * output was NULL. + // * Failure to adjust the number of available slots. This can + // happen because of trying to allocate/deallocate the async + // buffer in response to the value of producerControlledByApp. + // * DEAD_OBJECT - the token is hosted by an already-dead process + // + // Additional negative errors may be returned by the internals, they + // should be treated as opaque fatal unrecoverable errors. + virtual status_t connect(const sp<IProducerListener>& listener, + int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; + + enum class DisconnectMode { + // Disconnect only the specified API. + Api, + // Disconnect any API originally connected from the process calling disconnect. + AllLocal + }; + + // disconnect attempts to disconnect a client API from the + // IGraphicBufferProducer. Calling this method will cause any subsequent + // calls to other IGraphicBufferProducer methods to fail except for + // getAllocator and connect. Successfully calling connect after this will + // allow the other methods to succeed again. + // + // The api should be one of the NATIVE_WINDOW_API_* values in <window.h> + // + // Alternatively if mode is AllLocal, then the API value is ignored, and any API + // connected from the same PID calling disconnect will be disconnected. + // + // Disconnecting from an abandoned IGraphicBufferProducer is legal and + // is considered a no-op. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the producer is not connected + // * BAD_VALUE - one of the following has occurred: + // * the api specified does not match the one that was connected + // * api was out of range (see above). + // * DEAD_OBJECT - the token is hosted by an already-dead process + virtual status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) = 0; + + // Attaches a sideband buffer stream to the IGraphicBufferProducer. + // + // A sideband stream is a device-specific mechanism for passing buffers + // from the producer to the consumer without using dequeueBuffer/ + // queueBuffer. If a sideband stream is present, the consumer can choose + // whether to acquire buffers from the sideband stream or from the queued + // buffers. + // + // Passing NULL or a different stream handle will detach the previous + // handle if any. + virtual status_t setSidebandStream(const sp<NativeHandle>& stream) = 0; + + // Allocates buffers based on the given dimensions/format. + // + // This function will allocate up to the maximum number of buffers + // permitted by the current BufferQueue configuration. It will use the + // given format, dimensions, and usage bits, which are interpreted in the + // same way as for dequeueBuffer, and the async flag must be set the same + // way as for dequeueBuffer to ensure that the correct number of buffers are + // allocated. This is most useful to avoid an allocation delay during + // dequeueBuffer. If there are already the maximum number of buffers + // allocated, this function has no effect. + virtual void allocateBuffers(uint32_t width, uint32_t height, + PixelFormat format, uint32_t usage) = 0; + + // Sets whether dequeueBuffer is allowed to allocate new buffers. + // + // Normally dequeueBuffer does not discriminate between free slots which + // already have an allocated buffer and those which do not, and will + // allocate a new buffer if the slot doesn't have a buffer or if the slot's + // buffer doesn't match the requested size, format, or usage. This method + // allows the producer to restrict the eligible slots to those which already + // have an allocated buffer of the correct size, format, and usage. If no + // eligible slot is available, dequeueBuffer will block or return an error + // as usual. + virtual status_t allowAllocation(bool allow) = 0; + + // Sets the current generation number of the BufferQueue. + // + // This generation number will be inserted into any buffers allocated by the + // BufferQueue, and any attempts to attach a buffer with a different + // generation number will fail. Buffers already in the queue are not + // affected and will retain their current generation number. The generation + // number defaults to 0. + virtual status_t setGenerationNumber(uint32_t generationNumber) = 0; + + // Returns the name of the connected consumer. + virtual String8 getConsumerName() const = 0; + + // Used to enable/disable shared buffer mode. + // + // When shared buffer mode is enabled the first buffer that is queued or + // dequeued will be cached and returned to all subsequent calls to + // dequeueBuffer and acquireBuffer. This allows the producer and consumer to + // simultaneously access the same buffer. + virtual status_t setSharedBufferMode(bool sharedBufferMode) = 0; + + // Used to enable/disable auto-refresh. + // + // Auto refresh has no effect outside of shared buffer mode. In shared + // buffer mode, when enabled, it indicates to the consumer that it should + // attempt to acquire buffers even if it is not aware of any being + // available. + virtual status_t setAutoRefresh(bool autoRefresh) = 0; + + // Sets how long dequeueBuffer will wait for a buffer to become available + // before returning an error (TIMED_OUT). + // + // This timeout also affects the attachBuffer call, which will block if + // there is not a free slot available into which the attached buffer can be + // placed. + // + // By default, the BufferQueue will wait forever, which is indicated by a + // timeout of -1. If set (to a value other than -1), this will disable + // non-blocking mode and its corresponding spare buffer (which is used to + // ensure a buffer is always available). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - Failure to adjust the number of available slots. This can + // happen because of trying to allocate/deallocate the async + // buffer. + virtual status_t setDequeueTimeout(nsecs_t timeout) = 0; + + // Returns the last queued buffer along with a fence which must signal + // before the contents of the buffer are read. If there are no buffers in + // the queue, outBuffer will be populated with nullptr and outFence will be + // populated with Fence::NO_FENCE + // + // outTransformMatrix is not modified if outBuffer is null. + // + // Returns NO_ERROR or the status of the Binder transaction + virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence, float outTransformMatrix[16]) = 0; + + // Gets the frame events that haven't already been retrieved. + virtual void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) {} + + // Returns a unique id for this BufferQueue + virtual status_t getUniqueId(uint64_t* outId) const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnGraphicBufferProducer : public BnInterface<IGraphicBufferProducer> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h new file mode 100644 index 0000000000..e808bd3bc3 --- /dev/null +++ b/libs/gui/include/gui/IProducerListener.h @@ -0,0 +1,71 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IPRODUCERLISTENER_H +#define ANDROID_GUI_IPRODUCERLISTENER_H + +#include <binder/IInterface.h> + +#include <utils/RefBase.h> + +namespace android { + +// ProducerListener is the interface through which the BufferQueue notifies the +// producer of events that the producer may wish to react to. Because the +// producer will generally have a mutex that is locked during calls from the +// producer to the BufferQueue, these calls from the BufferQueue to the +// producer *MUST* be called only when the BufferQueue mutex is NOT locked. + +class ProducerListener : public virtual RefBase +{ +public: + ProducerListener() {} + virtual ~ProducerListener(); + + // onBufferReleased is called from IGraphicBufferConsumer::releaseBuffer to + // notify the producer that a new buffer is free and ready to be dequeued. + // + // This is called without any lock held and can be called concurrently by + // multiple threads. + virtual void onBufferReleased() = 0; // Asynchronous + virtual bool needsReleaseNotify() = 0; +}; + +class IProducerListener : public ProducerListener, public IInterface +{ +public: + DECLARE_META_INTERFACE(ProducerListener) +}; + +class BnProducerListener : public BnInterface<IProducerListener> +{ +public: + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); + virtual bool needsReleaseNotify(); +}; + +class DummyProducerListener : public BnProducerListener +{ +public: + virtual ~DummyProducerListener(); + virtual void onBufferReleased() {} + virtual bool needsReleaseNotify() { return false; } +}; + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h new file mode 100644 index 0000000000..f80ba000b4 --- /dev/null +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_ISURFACE_COMPOSER_H +#define ANDROID_GUI_ISURFACE_COMPOSER_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> +#include <utils/Timers.h> +#include <utils/Vector.h> + +#include <binder/IInterface.h> + +#include <ui/FrameStats.h> +#include <ui/PixelFormat.h> + +#include <vector> + +namespace android { +// ---------------------------------------------------------------------------- + +struct ComposerState; +struct DisplayState; +struct DisplayInfo; +struct DisplayStatInfo; +class HdrCapabilities; +class IDisplayEventConnection; +class IGraphicBufferProducer; +class ISurfaceComposerClient; +class Rect; +enum class FrameEvent; + +/* + * This class defines the Binder IPC interface for accessing various + * SurfaceFlinger features. + */ +class ISurfaceComposer: public IInterface { +public: + DECLARE_META_INTERFACE(SurfaceComposer) + + // flags for setTransactionState() + enum { + eSynchronous = 0x01, + eAnimation = 0x02, + }; + + enum { + eDisplayIdMain = 0, + eDisplayIdHdmi = 1 + }; + + enum Rotation { + eRotateNone = 0, + eRotate90 = 1, + eRotate180 = 2, + eRotate270 = 3 + }; + + enum VsyncSource { + eVsyncSourceApp = 0, + eVsyncSourceSurfaceFlinger = 1 + }; + + /* create connection with surface flinger, requires + * ACCESS_SURFACE_FLINGER permission + */ + virtual sp<ISurfaceComposerClient> createConnection() = 0; + + /** create a scoped connection with surface flinger. + * Surfaces produced with this connection will act + * as children of the passed in GBP. That is to say + * SurfaceFlinger will draw them relative and confined to + * drawing of buffers from the layer associated with parent. + * As this is graphically equivalent in reach to just drawing + * pixels into the parent buffers, it requires no special permission. + */ + virtual sp<ISurfaceComposerClient> createScopedConnection( + const sp<IGraphicBufferProducer>& parent) = 0; + + /* return an IDisplayEventConnection */ + virtual sp<IDisplayEventConnection> createDisplayEventConnection( + VsyncSource vsyncSource = eVsyncSourceApp) = 0; + + /* create a virtual display + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual sp<IBinder> createDisplay(const String8& displayName, + bool secure) = 0; + + /* destroy a virtual display + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual void destroyDisplay(const sp<IBinder>& display) = 0; + + /* get the token for the existing default displays. possible values + * for id are eDisplayIdMain and eDisplayIdHdmi. + */ + virtual sp<IBinder> getBuiltInDisplay(int32_t id) = 0; + + /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ + virtual void setTransactionState(const Vector<ComposerState>& state, + const Vector<DisplayState>& displays, uint32_t flags) = 0; + + /* signal that we're done booting. + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual void bootFinished() = 0; + + /* verify that an IGraphicBufferProducer was created by SurfaceFlinger. + */ + virtual bool authenticateSurfaceTexture( + const sp<IGraphicBufferProducer>& surface) const = 0; + + /* Returns the frame timestamps supported by SurfaceFlinger. + */ + virtual status_t getSupportedFrameTimestamps( + std::vector<FrameEvent>* outSupported) const = 0; + + /* set display power mode. depending on the mode, it can either trigger + * screen on, off or low power mode and wait for it to complete. + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual void setPowerMode(const sp<IBinder>& display, int mode) = 0; + + /* returns information for each configuration of the given display + * intended to be used to get information about built-in displays */ + virtual status_t getDisplayConfigs(const sp<IBinder>& display, + Vector<DisplayInfo>* configs) = 0; + + /* returns display statistics for a given display + * intended to be used by the media framework to properly schedule + * video frames */ + virtual status_t getDisplayStats(const sp<IBinder>& display, + DisplayStatInfo* stats) = 0; + + /* indicates which of the configurations returned by getDisplayInfo is + * currently active */ + virtual int getActiveConfig(const sp<IBinder>& display) = 0; + + /* specifies which configuration (of those returned by getDisplayInfo) + * should be used */ + virtual status_t setActiveConfig(const sp<IBinder>& display, int id) = 0; + + virtual status_t getDisplayColorModes(const sp<IBinder>& display, + Vector<android_color_mode_t>* outColorModes) = 0; + virtual android_color_mode_t getActiveColorMode(const sp<IBinder>& display) = 0; + virtual status_t setActiveColorMode(const sp<IBinder>& display, + android_color_mode_t colorMode) = 0; + + /* Capture the specified screen. requires READ_FRAME_BUFFER permission + * This function will fail if there is a secure window on screen. + */ + virtual status_t captureScreen(const sp<IBinder>& display, + const sp<IGraphicBufferProducer>& producer, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + int32_t minLayerZ, int32_t maxLayerZ, + bool useIdentityTransform, + Rotation rotation = eRotateNone) = 0; + + /* Clears the frame statistics for animations. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t clearAnimationFrameStats() = 0; + + /* Gets the frame statistics for animations. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t getAnimationFrameStats(FrameStats* outStats) const = 0; + + /* Gets the supported HDR capabilities of the given display. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t getHdrCapabilities(const sp<IBinder>& display, + HdrCapabilities* outCapabilities) const = 0; + + virtual status_t enableVSyncInjections(bool enable) = 0; + + virtual status_t injectVSync(nsecs_t when) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSurfaceComposer: public BnInterface<ISurfaceComposer> { +public: + enum { + // Note: BOOT_FINISHED must remain this value, it is called from + // Java by ActivityManagerService. + BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, + CREATE_CONNECTION, + UNUSED, // formerly CREATE_GRAPHIC_BUFFER_ALLOC + CREATE_DISPLAY_EVENT_CONNECTION, + CREATE_DISPLAY, + DESTROY_DISPLAY, + GET_BUILT_IN_DISPLAY, + SET_TRANSACTION_STATE, + AUTHENTICATE_SURFACE, + GET_SUPPORTED_FRAME_TIMESTAMPS, + GET_DISPLAY_CONFIGS, + GET_ACTIVE_CONFIG, + SET_ACTIVE_CONFIG, + CONNECT_DISPLAY, + CAPTURE_SCREEN, + CLEAR_ANIMATION_FRAME_STATS, + GET_ANIMATION_FRAME_STATS, + SET_POWER_MODE, + GET_DISPLAY_STATS, + GET_HDR_CAPABILITIES, + GET_DISPLAY_COLOR_MODES, + GET_ACTIVE_COLOR_MODE, + SET_ACTIVE_COLOR_MODE, + ENABLE_VSYNC_INJECTIONS, + INJECT_VSYNC, + CREATE_SCOPED_CONNECTION + }; + + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_GUI_ISURFACE_COMPOSER_H diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h new file mode 100644 index 0000000000..2c613ea8c5 --- /dev/null +++ b/libs/gui/include/gui/ISurfaceComposerClient.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <binder/IInterface.h> +#include <binder/SafeInterface.h> +#include <ui/PixelFormat.h> + +namespace android { + +class FrameStats; +class IGraphicBufferProducer; + +class ISurfaceComposerClient : public IInterface { +public: + DECLARE_META_INTERFACE(SurfaceComposerClient) + + // flags for createSurface() + enum { // (keep in sync with Surface.java) + eHidden = 0x00000004, + eDestroyBackbuffer = 0x00000020, + eSecure = 0x00000080, + eNonPremultiplied = 0x00000100, + eOpaque = 0x00000400, + eProtectedByApp = 0x00000800, + eProtectedByDRM = 0x00001000, + eCursorWindow = 0x00002000, + + eFXSurfaceNormal = 0x00000000, + eFXSurfaceDim = 0x00020000, + eFXSurfaceMask = 0x000F0000, + }; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, + uint32_t flags, const sp<IBinder>& parent, uint32_t windowType, + uint32_t ownerUid, sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t destroySurface(const sp<IBinder>& handle) = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0; +}; + +class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> { +public: + BnSurfaceComposerClient() + : SafeBnInterface<ISurfaceComposerClient>("BnSurfaceComposerClient") {} + + status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override; +}; + +} // namespace android diff --git a/libs/gui/include/gui/OccupancyTracker.h b/libs/gui/include/gui/OccupancyTracker.h new file mode 100644 index 0000000000..d4de8f2b14 --- /dev/null +++ b/libs/gui/include/gui/OccupancyTracker.h @@ -0,0 +1,104 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_GUI_OCCUPANCYTRACKER_H +#define ANDROID_GUI_OCCUPANCYTRACKER_H + +#include <binder/Parcelable.h> + +#include <utils/Timers.h> + +#include <deque> +#include <unordered_map> + +namespace android { + +class String8; + +class OccupancyTracker +{ +public: + OccupancyTracker() + : mPendingSegment(), + mSegmentHistory(), + mLastOccupancy(0), + mLastOccupancyChangeTime(0) {} + + struct Segment : public Parcelable { + Segment() + : totalTime(0), + numFrames(0), + occupancyAverage(0.0f), + usedThirdBuffer(false) {} + + Segment(nsecs_t _totalTime, size_t _numFrames, float _occupancyAverage, + bool _usedThirdBuffer) + : totalTime(_totalTime), + numFrames(_numFrames), + occupancyAverage(_occupancyAverage), + usedThirdBuffer(_usedThirdBuffer) {} + + // Parcelable interface + virtual status_t writeToParcel(Parcel* parcel) const override; + virtual status_t readFromParcel(const Parcel* parcel) override; + + nsecs_t totalTime; + size_t numFrames; + + // Average occupancy of the queue over this segment. (0.0, 1.0) implies + // double-buffered, (1.0, 2.0) implies triple-buffered. + float occupancyAverage; + + // Whether a third buffer was used at all during this segment (since a + // segment could read as double-buffered on average, but still require a + // third buffer to avoid jank for some smaller portion) + bool usedThirdBuffer; + }; + + void registerOccupancyChange(size_t occupancy); + std::vector<Segment> getSegmentHistory(bool forceFlush); + +private: + static constexpr size_t MAX_HISTORY_SIZE = 10; + static constexpr nsecs_t NEW_SEGMENT_DELAY = ms2ns(100); + static constexpr size_t LONG_SEGMENT_THRESHOLD = 3; + + struct PendingSegment { + void clear() { + totalTime = 0; + numFrames = 0; + mOccupancyTimes.clear(); + } + + nsecs_t totalTime; + size_t numFrames; + std::unordered_map<size_t, nsecs_t> mOccupancyTimes; + }; + + void recordPendingSegment(); + + PendingSegment mPendingSegment; + std::deque<Segment> mSegmentHistory; + + size_t mLastOccupancy; + nsecs_t mLastOccupancyChangeTime; + +}; // class OccupancyTracker + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/StreamSplitter.h b/libs/gui/include/gui/StreamSplitter.h new file mode 100644 index 0000000000..8f47eb47ac --- /dev/null +++ b/libs/gui/include/gui/StreamSplitter.h @@ -0,0 +1,184 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_STREAMSPLITTER_H +#define ANDROID_GUI_STREAMSPLITTER_H + +#include <gui/IConsumerListener.h> +#include <gui/IProducerListener.h> + +#include <utils/Condition.h> +#include <utils/KeyedVector.h> +#include <utils/Mutex.h> +#include <utils/StrongPointer.h> + +namespace android { + +class GraphicBuffer; +class IGraphicBufferConsumer; +class IGraphicBufferProducer; + +// StreamSplitter is an autonomous class that manages one input BufferQueue +// and multiple output BufferQueues. By using the buffer attach and detach logic +// in BufferQueue, it is able to present the illusion of a single split +// BufferQueue, where each buffer queued to the input is available to be +// acquired by each of the outputs, and is able to be dequeued by the input +// again only once all of the outputs have released it. +class StreamSplitter : public BnConsumerListener { +public: + // createSplitter creates a new splitter, outSplitter, using inputQueue as + // the input BufferQueue. Output BufferQueues must be added using addOutput + // before queueing any buffers to the input. + // + // A return value other than NO_ERROR means that an error has occurred and + // outSplitter has not been modified. BAD_VALUE is returned if inputQueue or + // outSplitter is NULL. See IGraphicBufferConsumer::consumerConnect for + // explanations of other error codes. + static status_t createSplitter(const sp<IGraphicBufferConsumer>& inputQueue, + sp<StreamSplitter>* outSplitter); + + // addOutput adds an output BufferQueue to the splitter. The splitter + // connects to outputQueue as a CPU producer, and any buffers queued + // to the input will be queued to each output. It is assumed that all of the + // outputs are added before any buffers are queued on the input. If any + // output is abandoned by its consumer, the splitter will abandon its input + // queue (see onAbandoned). + // + // A return value other than NO_ERROR means that an error has occurred and + // outputQueue has not been added to the splitter. BAD_VALUE is returned if + // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations + // of other error codes. + status_t addOutput(const sp<IGraphicBufferProducer>& outputQueue); + + // setName sets the consumer name of the input queue + void setName(const String8& name); + +private: + // From IConsumerListener + // + // During this callback, we store some tracking information, detach the + // buffer from the input, and attach it to each of the outputs. This call + // can block if there are too many outstanding buffers. If it blocks, it + // will resume when onBufferReleasedByOutput releases a buffer back to the + // input. + virtual void onFrameAvailable(const BufferItem& item); + + // From IConsumerListener + // We don't care about released buffers because we detach each buffer as + // soon as we acquire it. See the comment for onBufferReleased below for + // some clarifying notes about the name. + virtual void onBuffersReleased() {} + + // From IConsumerListener + // We don't care about sideband streams, since we won't be splitting them + virtual void onSidebandStreamChanged() {} + + // This is the implementation of the onBufferReleased callback from + // IProducerListener. It gets called from an OutputListener (see below), and + // 'from' is which producer interface from which the callback was received. + // + // During this callback, we detach the buffer from the output queue that + // generated the callback, update our state tracking to see if this is the + // last output releasing the buffer, and if so, release it to the input. + // If we release the buffer to the input, we allow a blocked + // onFrameAvailable call to proceed. + void onBufferReleasedByOutput(const sp<IGraphicBufferProducer>& from); + + // When this is called, the splitter disconnects from (i.e., abandons) its + // input queue and signals any waiting onFrameAvailable calls to wake up. + // It still processes callbacks from other outputs, but only detaches their + // buffers so they can continue operating until they run out of buffers to + // acquire. This must be called with mMutex locked. + void onAbandonedLocked(); + + // This is a thin wrapper class that lets us determine which BufferQueue + // the IProducerListener::onBufferReleased callback is associated with. We + // create one of these per output BufferQueue, and then pass the producer + // into onBufferReleasedByOutput above. + class OutputListener : public BnProducerListener, + public IBinder::DeathRecipient { + public: + OutputListener(const sp<StreamSplitter>& splitter, + const sp<IGraphicBufferProducer>& output); + virtual ~OutputListener(); + + // From IProducerListener + virtual void onBufferReleased(); + + // From IBinder::DeathRecipient + virtual void binderDied(const wp<IBinder>& who); + + private: + sp<StreamSplitter> mSplitter; + sp<IGraphicBufferProducer> mOutput; + }; + + class BufferTracker : public LightRefBase<BufferTracker> { + public: + BufferTracker(const sp<GraphicBuffer>& buffer); + + const sp<GraphicBuffer>& getBuffer() const { return mBuffer; } + const sp<Fence>& getMergedFence() const { return mMergedFence; } + + void mergeFence(const sp<Fence>& with); + + // Returns the new value + // Only called while mMutex is held + size_t incrementReleaseCountLocked() { return ++mReleaseCount; } + + private: + // Only destroy through LightRefBase + friend LightRefBase<BufferTracker>; + ~BufferTracker(); + + // Disallow copying + BufferTracker(const BufferTracker& other); + BufferTracker& operator=(const BufferTracker& other); + + sp<GraphicBuffer> mBuffer; // One instance that holds this native handle + sp<Fence> mMergedFence; + size_t mReleaseCount; + }; + + // Only called from createSplitter + StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue); + + // Must be accessed through RefBase + virtual ~StreamSplitter(); + + static const int MAX_OUTSTANDING_BUFFERS = 2; + + // mIsAbandoned is set to true when an output dies. Once the StreamSplitter + // has been abandoned, it will continue to detach buffers from other + // outputs, but it will disconnect from the input and not attempt to + // communicate with it further. + bool mIsAbandoned; + + Mutex mMutex; + Condition mReleaseCondition; + int mOutstandingBuffers; + sp<IGraphicBufferConsumer> mInput; + Vector<sp<IGraphicBufferProducer> > mOutputs; + + // Map of GraphicBuffer IDs (GraphicBuffer::getId()) to buffer tracking + // objects (which are mostly for counting how many outputs have released the + // buffer, but also contain merged release fences). + KeyedVector<uint64_t, sp<BufferTracker> > mBuffers; +}; + +} // namespace android + +#endif diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h new file mode 100644 index 0000000000..e8dc83e951 --- /dev/null +++ b/libs/gui/include/gui/Surface.h @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_H +#define ANDROID_GUI_SURFACE_H + +#include <gui/IGraphicBufferProducer.h> +#include <gui/BufferQueueDefs.h> + +#include <ui/ANativeObjectBase.h> +#include <ui/Region.h> + +#include <utils/Condition.h> +#include <utils/Mutex.h> +#include <utils/RefBase.h> + +struct ANativeWindow_Buffer; + +namespace android { + +class ISurfaceComposer; + +/* + * An implementation of ANativeWindow that feeds graphics buffers into a + * BufferQueue. + * + * This is typically used by programs that want to render frames through + * some means (maybe OpenGL, a software renderer, or a hardware decoder) + * and have the frames they create forwarded to SurfaceFlinger for + * compositing. For example, a video decoder could render a frame and call + * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by + * Surface. Surface then forwards the buffers through Binder IPC + * to the BufferQueue's producer interface, providing the new frame to a + * consumer such as GLConsumer. + */ +class Surface + : public ANativeObjectBase<ANativeWindow, Surface, RefBase> +{ +public: + + /* + * creates a Surface from the given IGraphicBufferProducer (which concrete + * implementation is a BufferQueue). + * + * Surface is mainly state-less while it's disconnected, it can be + * viewed as a glorified IGraphicBufferProducer holder. It's therefore + * safe to create other Surfaces from the same IGraphicBufferProducer. + * + * However, once a Surface is connected, it'll prevent other Surfaces + * referring to the same IGraphicBufferProducer to become connected and + * therefore prevent them to be used as actual producers of buffers. + * + * the controlledByApp flag indicates that this Surface (producer) is + * controlled by the application. This flag is used at connect time. + */ + explicit Surface(const sp<IGraphicBufferProducer>& bufferProducer, + bool controlledByApp = false); + + /* getIGraphicBufferProducer() returns the IGraphicBufferProducer this + * Surface was created with. Usually it's an error to use the + * IGraphicBufferProducer while the Surface is connected. + */ + sp<IGraphicBufferProducer> getIGraphicBufferProducer() const; + + /* convenience function to check that the given surface is non NULL as + * well as its IGraphicBufferProducer */ + static bool isValid(const sp<Surface>& surface) { + return surface != NULL && surface->getIGraphicBufferProducer() != NULL; + } + + /* Attaches a sideband buffer stream to the Surface's IGraphicBufferProducer. + * + * A sideband stream is a device-specific mechanism for passing buffers + * from the producer to the consumer without using dequeueBuffer/ + * queueBuffer. If a sideband stream is present, the consumer can choose + * whether to acquire buffers from the sideband stream or from the queued + * buffers. + * + * Passing NULL or a different stream handle will detach the previous + * handle if any. + */ + void setSidebandStream(const sp<NativeHandle>& stream); + + /* Allocates buffers based on the current dimensions/format. + * + * This function will allocate up to the maximum number of buffers + * permitted by the current BufferQueue configuration. It will use the + * default format and dimensions. This is most useful to avoid an allocation + * delay during dequeueBuffer. If there are already the maximum number of + * buffers allocated, this function has no effect. + */ + void allocateBuffers(); + + /* Sets the generation number on the IGraphicBufferProducer and updates the + * generation number on any buffers attached to the Surface after this call. + * See IGBP::setGenerationNumber for more information. */ + status_t setGenerationNumber(uint32_t generationNumber); + + // See IGraphicBufferProducer::getConsumerName + String8 getConsumerName() const; + + // See IGraphicBufferProducer::getNextFrameNumber + uint64_t getNextFrameNumber() const; + + /* Set the scaling mode to be used with a Surface. + * See NATIVE_WINDOW_SET_SCALING_MODE and its parameters + * in <system/window.h>. */ + int setScalingMode(int mode); + + // See IGraphicBufferProducer::setDequeueTimeout + status_t setDequeueTimeout(nsecs_t timeout); + + /* + * Wait for frame number to increase past lastFrame for at most + * timeoutNs. Useful for one thread to wait for another unknown + * thread to queue a buffer. + */ + bool waitForNextFrame(uint64_t lastFrame, nsecs_t timeout); + + // See IGraphicBufferProducer::getLastQueuedBuffer + // See GLConsumer::getTransformMatrix for outTransformMatrix format + status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence, float outTransformMatrix[16]); + + status_t getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration); + + /* Enables or disables frame timestamp tracking. It is disabled by default + * to avoid overhead during queue and dequeue for applications that don't + * need the feature. If disabled, calls to getFrameTimestamps will fail. + */ + void enableFrameTimestamps(bool enable); + + status_t getCompositorTiming( + nsecs_t* compositeDeadline, nsecs_t* compositeInterval, + nsecs_t* compositeToPresentLatency); + + // See IGraphicBufferProducer::getFrameTimestamps + status_t getFrameTimestamps(uint64_t frameNumber, + nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, + nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime, + nsecs_t* outLastRefreshStartTime, nsecs_t* outGlCompositionDoneTime, + nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime, + nsecs_t* outReleaseTime); + + status_t getWideColorSupport(bool* supported); + status_t getHdrSupport(bool* supported); + + status_t getUniqueId(uint64_t* outId) const; + + // Returns the CLOCK_MONOTONIC start time of the last dequeueBuffer call + nsecs_t getLastDequeueStartTime() const; + +protected: + virtual ~Surface(); + + // Virtual for testing. + virtual sp<ISurfaceComposer> composerService() const; + virtual nsecs_t now() const; + +private: + // can't be copied + Surface& operator = (const Surface& rhs); + Surface(const Surface& rhs); + + // ANativeWindow hooks + static int hook_cancelBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_dequeueBuffer(ANativeWindow* window, + ANativeWindowBuffer** buffer, int* fenceFd); + static int hook_perform(ANativeWindow* window, int operation, ...); + static int hook_query(const ANativeWindow* window, int what, int* value); + static int hook_queueBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_setSwapInterval(ANativeWindow* window, int interval); + + static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer** buffer); + static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + + int dispatchConnect(va_list args); + int dispatchDisconnect(va_list args); + int dispatchSetBufferCount(va_list args); + int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersDimensions(va_list args); + int dispatchSetBuffersUserDimensions(va_list args); + int dispatchSetBuffersFormat(va_list args); + int dispatchSetScalingMode(va_list args); + int dispatchSetBuffersTransform(va_list args); + int dispatchSetBuffersStickyTransform(va_list args); + int dispatchSetBuffersTimestamp(va_list args); + int dispatchSetCrop(va_list args); + int dispatchSetPostTransformCrop(va_list args); + int dispatchSetUsage(va_list args); + int dispatchLock(va_list args); + int dispatchUnlockAndPost(va_list args); + int dispatchSetSidebandStream(va_list args); + int dispatchSetBuffersDataSpace(va_list args); + int dispatchSetSurfaceDamage(va_list args); + int dispatchSetSharedBufferMode(va_list args); + int dispatchSetAutoRefresh(va_list args); + int dispatchGetDisplayRefreshCycleDuration(va_list args); + int dispatchGetNextFrameId(va_list args); + int dispatchEnableFrameTimestamps(va_list args); + int dispatchGetCompositorTiming(va_list args); + int dispatchGetFrameTimestamps(va_list args); + int dispatchGetWideColorSupport(va_list args); + int dispatchGetHdrSupport(va_list args); + +protected: + virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); + virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int perform(int operation, va_list args); + virtual int setSwapInterval(int interval); + + virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); + + virtual int connect(int api); + virtual int setBufferCount(int bufferCount); + virtual int setBuffersUserDimensions(uint32_t width, uint32_t height); + virtual int setBuffersFormat(PixelFormat format); + virtual int setBuffersTransform(uint32_t transform); + virtual int setBuffersStickyTransform(uint32_t transform); + virtual int setBuffersTimestamp(int64_t timestamp); + virtual int setBuffersDataSpace(android_dataspace dataSpace); + virtual int setCrop(Rect const* rect); + virtual int setUsage(uint32_t reqUsage); + virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects); + +public: + virtual int disconnect(int api, + IGraphicBufferProducer::DisconnectMode mode = + IGraphicBufferProducer::DisconnectMode::Api); + + virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers); + virtual int setAsyncMode(bool async); + virtual int setSharedBufferMode(bool sharedBufferMode); + virtual int setAutoRefresh(bool autoRefresh); + virtual int setBuffersDimensions(uint32_t width, uint32_t height); + virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); + virtual int unlockAndPost(); + virtual int query(int what, int* value) const; + + virtual int connect(int api, const sp<IProducerListener>& listener); + + // When reportBufferRemoval is true, clients must call getAndFlushRemovedBuffers to fetch + // GraphicBuffers removed from this surface after a dequeueBuffer, detachNextBuffer or + // attachBuffer call. This allows clients with their own buffer caches to free up buffers no + // longer in use by this surface. + virtual int connect( + int api, const sp<IProducerListener>& listener, + bool reportBufferRemoval); + virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence); + virtual int attachBuffer(ANativeWindowBuffer*); + + // When client connects to Surface with reportBufferRemoval set to true, any buffers removed + // from this Surface will be collected and returned here. Once this method returns, these + // buffers will no longer be referenced by this Surface unless they are attached to this + // Surface later. The list of removed buffers will only be stored until the next dequeueBuffer, + // detachNextBuffer, or attachBuffer call. + status_t getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out); + +protected: + enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS }; + enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; + + void querySupportedTimestampsLocked() const; + + void freeAllBuffers(); + int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; + + struct BufferSlot { + sp<GraphicBuffer> buffer; + Region dirtyRegion; + }; + + // mSurfaceTexture is the interface to the surface texture server. All + // operations on the surface texture client ultimately translate into + // interactions with the server using this interface. + // TODO: rename to mBufferProducer + sp<IGraphicBufferProducer> mGraphicBufferProducer; + + // mSlots stores the buffers that have been allocated for each buffer slot. + // It is initialized to null pointers, and gets filled in with the result of + // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + BufferSlot mSlots[NUM_BUFFER_SLOTS]; + + // mReqWidth is the buffer width that will be requested at the next dequeue + // operation. It is initialized to 1. + uint32_t mReqWidth; + + // mReqHeight is the buffer height that will be requested at the next + // dequeue operation. It is initialized to 1. + uint32_t mReqHeight; + + // mReqFormat is the buffer pixel format that will be requested at the next + // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. + PixelFormat mReqFormat; + + // mReqUsage is the set of buffer usage flags that will be requested + // at the next deuque operation. It is initialized to 0. + uint32_t mReqUsage; + + // mTimestamp is the timestamp that will be used for the next buffer queue + // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that + // a timestamp is auto-generated when queueBuffer is called. + int64_t mTimestamp; + + // mDataSpace is the buffer dataSpace that will be used for the next buffer + // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which + // means that the buffer contains some type of color data. + android_dataspace mDataSpace; + + // mCrop is the crop rectangle that will be used for the next buffer + // that gets queued. It is set by calling setCrop. + Rect mCrop; + + // mScalingMode is the scaling mode that will be used for the next + // buffers that get queued. It is set by calling setScalingMode. + int mScalingMode; + + // mTransform is the transform identifier that will be used for the next + // buffer that gets queued. It is set by calling setTransform. + uint32_t mTransform; + + // mStickyTransform is a transform that is applied on top of mTransform + // in each buffer that is queued. This is typically used to force the + // compositor to apply a transform, and will prevent the transform hint + // from being set by the compositor. + uint32_t mStickyTransform; + + // mDefaultWidth is default width of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultWidth; + + // mDefaultHeight is default height of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultHeight; + + // mUserWidth, if non-zero, is an application-specified override + // of mDefaultWidth. This is lower priority than the width set by + // native_window_set_buffers_dimensions. + uint32_t mUserWidth; + + // mUserHeight, if non-zero, is an application-specified override + // of mDefaultHeight. This is lower priority than the height set + // by native_window_set_buffers_dimensions. + uint32_t mUserHeight; + + // mTransformHint is the transform probably applied to buffers of this + // window. this is only a hint, actual transform may differ. + uint32_t mTransformHint; + + // mProducerControlledByApp whether this buffer producer is controlled + // by the application + bool mProducerControlledByApp; + + // mSwapIntervalZero set if we should drop buffers at queue() time to + // achieve an asynchronous swap interval + bool mSwapIntervalZero; + + // mConsumerRunningBehind whether the consumer is running more than + // one buffer behind the producer. + mutable bool mConsumerRunningBehind; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of Surface objects. It must be locked whenever the + // member variables are accessed. + mutable Mutex mMutex; + + // must be used from the lock/unlock thread + sp<GraphicBuffer> mLockedBuffer; + sp<GraphicBuffer> mPostedBuffer; + bool mConnectedToCpu; + + // When a CPU producer is attached, this reflects the region that the + // producer wished to update as well as whether the Surface was able to copy + // the previous buffer back to allow a partial update. + // + // When a non-CPU producer is attached, this reflects the surface damage + // (the change since the previous frame) passed in by the producer. + Region mDirtyRegion; + + // Stores the current generation number. See setGenerationNumber and + // IGraphicBufferProducer::setGenerationNumber for more information. + uint32_t mGenerationNumber; + + // Caches the values that have been passed to the producer. + bool mSharedBufferMode; + bool mAutoRefresh; + + // If in shared buffer mode and auto refresh is enabled, store the shared + // buffer slot and return it for all calls to queue/dequeue without going + // over Binder. + int mSharedBufferSlot; + + // This is true if the shared buffer has already been queued/canceled. It's + // used to prevent a mismatch between the number of queue/dequeue calls. + bool mSharedBufferHasBeenQueued; + + // These are used to satisfy the NATIVE_WINDOW_LAST_*_DURATION queries + nsecs_t mLastDequeueDuration = 0; + nsecs_t mLastQueueDuration = 0; + + // Stores the time right before we call IGBP::dequeueBuffer + nsecs_t mLastDequeueStartTime = 0; + + Condition mQueueBufferCondition; + + uint64_t mNextFrameNumber = 1; + uint64_t mLastFrameNumber = 0; + + // Mutable because ANativeWindow::query needs this class const. + mutable bool mQueriedSupportedTimestamps; + mutable bool mFrameTimestampsSupportsPresent; + + // A cached copy of the FrameEventHistory maintained by the consumer. + bool mEnableFrameTimestamps = false; + std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory; + + bool mReportRemovedBuffers = false; + std::vector<sp<GraphicBuffer>> mRemovedBuffers; +}; + +} // namespace android + +#endif // ANDROID_GUI_SURFACE_H diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h new file mode 100644 index 0000000000..ec310cf6f9 --- /dev/null +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H +#define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H + +#include <stdint.h> +#include <sys/types.h> + +#include <binder/IBinder.h> + +#include <utils/RefBase.h> +#include <utils/Singleton.h> +#include <utils/SortedVector.h> +#include <utils/threads.h> + +#include <ui/FrameStats.h> +#include <ui/PixelFormat.h> + +#include <gui/CpuConsumer.h> +#include <gui/SurfaceControl.h> + +namespace android { + +// --------------------------------------------------------------------------- + +struct DisplayInfo; +class Composer; +class HdrCapabilities; +class ISurfaceComposerClient; +class IGraphicBufferProducer; +class Region; + +// --------------------------------------------------------------------------- + +class SurfaceComposerClient : public RefBase +{ + friend class Composer; +public: + SurfaceComposerClient(); + SurfaceComposerClient(const sp<IGraphicBufferProducer>& parent); + virtual ~SurfaceComposerClient(); + + // Always make sure we could initialize + status_t initCheck() const; + + // Return the connection of this client + sp<IBinder> connection() const; + + // Forcibly remove connection before all references have gone away. + void dispose(); + + // callback when the composer is dies + status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient, + void* cookie = NULL, uint32_t flags = 0); + + // Get a list of supported configurations for a given display + static status_t getDisplayConfigs(const sp<IBinder>& display, + Vector<DisplayInfo>* configs); + + // Get the DisplayInfo for the currently-active configuration + static status_t getDisplayInfo(const sp<IBinder>& display, + DisplayInfo* info); + + // Get the index of the current active configuration (relative to the list + // returned by getDisplayInfo) + static int getActiveConfig(const sp<IBinder>& display); + + // Set a new active configuration using an index relative to the list + // returned by getDisplayInfo + static status_t setActiveConfig(const sp<IBinder>& display, int id); + + // Gets the list of supported color modes for the given display + static status_t getDisplayColorModes(const sp<IBinder>& display, + Vector<android_color_mode_t>* outColorModes); + + // Gets the active color mode for the given display + static android_color_mode_t getActiveColorMode(const sp<IBinder>& display); + + // Sets the active color mode for the given display + static status_t setActiveColorMode(const sp<IBinder>& display, android_color_mode_t colorMode); + + /* Triggers screen on/off or low power mode and waits for it to complete */ + static void setDisplayPowerMode(const sp<IBinder>& display, int mode); + + // ------------------------------------------------------------------------ + // surface creation / destruction + + //! Create a surface + sp<SurfaceControl> createSurface( + const String8& name,// name of the surface + uint32_t w, // width in pixel + uint32_t h, // height in pixel + PixelFormat format, // pixel-format desired + uint32_t flags = 0, // usage flags + SurfaceControl* parent = nullptr, // parent + uint32_t windowType = 0, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.) + uint32_t ownerUid = 0 // UID of the task + ); + + //! Create a virtual display + static sp<IBinder> createDisplay(const String8& displayName, bool secure); + + //! Destroy a virtual display + static void destroyDisplay(const sp<IBinder>& display); + + //! Get the token for the existing default displays. + //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. + static sp<IBinder> getBuiltInDisplay(int32_t id); + + // ------------------------------------------------------------------------ + // Composer parameters + // All composer parameters must be changed within a transaction + // several surfaces can be updated in one transaction, all changes are + // committed at once when the transaction is closed. + // closeGlobalTransaction() requires an IPC with the server. + + //! Open a composer transaction on all active SurfaceComposerClients. + static void openGlobalTransaction(); + + //! Close a composer transaction on all active SurfaceComposerClients. + static void closeGlobalTransaction(bool synchronous = false); + + static status_t enableVSyncInjections(bool enable); + + static status_t injectVSync(nsecs_t when); + + //! Flag the currently open transaction as an animation transaction. + static void setAnimationTransaction(); + + status_t hide(const sp<IBinder>& id); + status_t show(const sp<IBinder>& id); + status_t setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent); + status_t setLayer(const sp<IBinder>& id, int32_t layer); + status_t setRelativeLayer(const sp<IBinder>& id, + const sp<IBinder>& relativeTo, int32_t layer); + status_t setAlpha(const sp<IBinder>& id, float alpha=1.0f); + status_t setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dtdy, float dsdy); + status_t setPosition(const sp<IBinder>& id, float x, float y); + status_t setSize(const sp<IBinder>& id, uint32_t w, uint32_t h); + status_t setCrop(const sp<IBinder>& id, const Rect& crop); + status_t setFinalCrop(const sp<IBinder>& id, const Rect& crop); + status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); + status_t deferTransactionUntil(const sp<IBinder>& id, + const sp<IBinder>& handle, uint64_t frameNumber); + status_t deferTransactionUntil(const sp<IBinder>& id, + const sp<Surface>& handle, uint64_t frameNumber); + status_t reparentChildren(const sp<IBinder>& id, + const sp<IBinder>& newParentHandle); + status_t detachChildren(const sp<IBinder>& id); + status_t setOverrideScalingMode(const sp<IBinder>& id, + int32_t overrideScalingMode); + status_t setGeometryAppliesWithResize(const sp<IBinder>& id); + + status_t destroySurface(const sp<IBinder>& id); + + status_t clearLayerFrameStats(const sp<IBinder>& token) const; + status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const; + + static status_t clearAnimationFrameStats(); + static status_t getAnimationFrameStats(FrameStats* outStats); + + static status_t getHdrCapabilities(const sp<IBinder>& display, + HdrCapabilities* outCapabilities); + + static status_t setDisplaySurface(const sp<IBinder>& token, + sp<IGraphicBufferProducer> bufferProducer); + static void setDisplayLayerStack(const sp<IBinder>& token, + uint32_t layerStack); + static void setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height); + + /* setDisplayProjection() defines the projection of layer stacks + * to a given display. + * + * - orientation defines the display's orientation. + * - layerStackRect defines which area of the window manager coordinate + * space will be used. + * - displayRect defines where on the display will layerStackRect be + * mapped to. displayRect is specified post-orientation, that is + * it uses the orientation seen by the end-user. + */ + static void setDisplayProjection(const sp<IBinder>& token, + uint32_t orientation, + const Rect& layerStackRect, + const Rect& displayRect); + +private: + virtual void onFirstRef(); + Composer& getComposer(); + + mutable Mutex mLock; + status_t mStatus; + sp<ISurfaceComposerClient> mClient; + Composer& mComposer; + wp<IGraphicBufferProducer> mParent; +}; + +// --------------------------------------------------------------------------- + +class ScreenshotClient +{ +public: + // if cropping isn't required, callers may pass in a default Rect, e.g.: + // capture(display, producer, Rect(), reqWidth, ...); + static status_t capture( + const sp<IBinder>& display, + const sp<IGraphicBufferProducer>& producer, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + int32_t minLayerZ, int32_t maxLayerZ, + bool useIdentityTransform); + static status_t captureToBuffer( + const sp<IBinder>& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + int32_t minLayerZ, int32_t maxLayerZ, + bool useIdentityTransform, + uint32_t rotation, + sp<GraphicBuffer>* outbuffer); +private: + mutable sp<CpuConsumer> mCpuConsumer; + mutable sp<IGraphicBufferProducer> mProducer; + CpuConsumer::LockedBuffer mBuffer; + bool mHaveBuffer; + +public: + ScreenshotClient(); + ~ScreenshotClient(); + + // frees the previous screenshot and captures a new one + // if cropping isn't required, callers may pass in a default Rect, e.g.: + // update(display, Rect(), useIdentityTransform); + status_t update(const sp<IBinder>& display, + Rect sourceCrop, bool useIdentityTransform); + status_t update(const sp<IBinder>& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + bool useIdentityTransform); + status_t update(const sp<IBinder>& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + int32_t minLayerZ, int32_t maxLayerZ, + bool useIdentityTransform); + status_t update(const sp<IBinder>& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + int32_t minLayerZ, int32_t maxLayerZ, + bool useIdentityTransform, uint32_t rotation); + + sp<CpuConsumer> getCpuConsumer() const; + + // release memory occupied by the screenshot + void release(); + + // pixels are valid until this object is freed or + // release() or update() is called + void const* getPixels() const; + + uint32_t getWidth() const; + uint32_t getHeight() const; + PixelFormat getFormat() const; + uint32_t getStride() const; + // size of allocated memory in bytes + size_t getSize() const; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h new file mode 100644 index 0000000000..8bb705cf77 --- /dev/null +++ b/libs/gui/include/gui/SurfaceControl.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_CONTROL_H +#define ANDROID_GUI_SURFACE_CONTROL_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +#include <ui/FrameStats.h> +#include <ui/PixelFormat.h> +#include <ui/Region.h> + +#include <gui/ISurfaceComposerClient.h> + +namespace android { + +// --------------------------------------------------------------------------- + +class IGraphicBufferProducer; +class Surface; +class SurfaceComposerClient; + +// --------------------------------------------------------------------------- + +class SurfaceControl : public RefBase +{ +public: + static bool isValid(const sp<SurfaceControl>& surface) { + return (surface != 0) && surface->isValid(); + } + + bool isValid() { + return mHandle!=0 && mClient!=0; + } + + static bool isSameSurface( + const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); + + // release surface data from java + void clear(); + + // disconnect any api that's connected + void disconnect(); + + status_t setLayerStack(uint32_t layerStack); + status_t setLayer(int32_t layer); + + // Sets a Z order relative to the Surface specified by "relativeTo" but + // without becoming a full child of the relative. Z-ordering works exactly + // as if it were a child however. + // + // As a nod to sanity, only non-child surfaces may have a relative Z-order. + // + // This overrides any previous and is overriden by any future calls + // to setLayer. + // + // If the relative dissapears, the Surface will have no layer and be + // invisible, until the next time set(Relative)Layer is called. + // + // TODO: This is probably a hack. Currently it exists only to work around + // some framework usage of the hidden APPLICATION_MEDIA_OVERLAY window type + // which allows inserting a window between a SurfaceView and it's main application + // window. However, since we are using child windows for the SurfaceView, but not using + // child windows elsewhere in O, the WindowManager can't set the layer appropriately. + // This is only used by the "TvInputService" and following the port of ViewRootImpl + // to child surfaces, we can then port this and remove this method. + status_t setRelativeLayer(const sp<IBinder>& relativeTo, int32_t layer); + status_t setPosition(float x, float y); + status_t setSize(uint32_t w, uint32_t h); + status_t hide(); + status_t show(); + status_t setFlags(uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const Region& transparent); + status_t setAlpha(float alpha=1.0f); + status_t setMatrix(float dsdx, float dtdx, float dtdy, float dsdy); + status_t setCrop(const Rect& crop); + status_t setFinalCrop(const Rect& crop); + + // If the size changes in this transaction, all geometry updates specified + // in this transaction will not complete until a buffer of the new size + // arrives. As some elements normally apply immediately, this enables + // freezing the total geometry of a surface until a resize is completed. + status_t setGeometryAppliesWithResize(); + + // Defers applying any changes made in this transaction until the Layer + // identified by handle reaches the given frameNumber. If the Layer identified + // by handle is removed, then we will apply this transaction regardless of + // what frame number has been reached. + status_t deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); + + // A variant of deferTransactionUntil which identifies the Layer we wait for by + // Surface instead of Handle. Useful for clients which may not have the + // SurfaceControl for some of their Surfaces. Otherwise behaves identically. + status_t deferTransactionUntil(const sp<Surface>& barrier, uint64_t frameNumber); + + // Reparents all children of this layer to the new parent handle. + status_t reparentChildren(const sp<IBinder>& newParentHandle); + + // Detaches all child surfaces (and their children recursively) + // from their SurfaceControl. + // The child SurfaceControl's will not throw exceptions or return errors, + // but transactions will have no effect. + // The child surfaces will continue to follow their parent surfaces, + // and remain eligible for rendering, but their relative state will be + // frozen. We use this in the WindowManager, in app shutdown/relaunch + // scenarios, where the app would otherwise clean up its child Surfaces. + // Sometimes the WindowManager needs to extend their lifetime slightly + // in order to perform an exit animation or prevent flicker. + status_t detachChildren(); + + // Set an override scaling mode as documented in <system/window.h> + // the override scaling mode will take precedence over any client + // specified scaling mode. -1 will clear the override scaling mode. + status_t setOverrideScalingMode(int32_t overrideScalingMode); + + static status_t writeSurfaceToParcel( + const sp<SurfaceControl>& control, Parcel* parcel); + + sp<Surface> getSurface() const; + sp<Surface> createSurface() const; + sp<IBinder> getHandle() const; + + status_t clearLayerFrameStats() const; + status_t getLayerFrameStats(FrameStats* outStats) const; + +private: + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class SurfaceComposerClient; + friend class Surface; + + SurfaceControl( + const sp<SurfaceComposerClient>& client, + const sp<IBinder>& handle, + const sp<IGraphicBufferProducer>& gbp); + + ~SurfaceControl(); + + sp<Surface> generateSurfaceLocked() const; + status_t validate() const; + void destroy(); + + sp<SurfaceComposerClient> mClient; + sp<IBinder> mHandle; + sp<IGraphicBufferProducer> mGraphicBufferProducer; + mutable Mutex mLock; + mutable sp<Surface> mSurfaceData; +}; + +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_CONTROL_H diff --git a/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h new file mode 100644 index 0000000000..fa6c2d9f7f --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h @@ -0,0 +1,66 @@ +/* + * Copyright 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_B2HPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_B2HPRODUCERLISTENER_H + +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> + +#include <binder/IBinder.h> +#include <gui/IProducerListener.h> + +#include <android/hidl/base/1.0/IBase.h> +#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V1_0 { +namespace utils { + +using ::android::hidl::base::V1_0::IBase; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +typedef ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener + HProducerListener; + +typedef ::android::IProducerListener + BProducerListener; + +struct B2HProducerListener : public HProducerListener { + sp<BProducerListener> mBase; + B2HProducerListener(sp<BProducerListener> const& base); + Return<void> onBufferReleased() override; + Return<bool> needsReleaseNotify() override; +}; + +} // namespace utils +} // namespace V1_0 +} // namespace omx +} // namespace media +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_B2HPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h new file mode 100644 index 0000000000..93c452a0d6 --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h @@ -0,0 +1,106 @@ +/* + * Copyright 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BGRAPHICBUFFERPRODUCER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BGRAPHICBUFFERPRODUCER_H + +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> + +#include <binder/Binder.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> + +#include <hidl/HybridInterface.h> +#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V1_0 { +namespace utils { + +using ::android::hidl::base::V1_0::IBase; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; + +using ::android::hardware::graphics::common::V1_0::PixelFormat; +using ::android::hardware::media::V1_0::AnwBuffer; + +typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer + HGraphicBufferProducer; +typedef ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener + HProducerListener; + +typedef ::android::IGraphicBufferProducer BGraphicBufferProducer; +using ::android::BnGraphicBufferProducer; +using ::android::IProducerListener; + +struct H2BGraphicBufferProducer : public ::android::H2BConverter< + HGraphicBufferProducer, + BGraphicBufferProducer, + BnGraphicBufferProducer> { + H2BGraphicBufferProducer(sp<HGraphicBufferProducer> const& base) : CBase(base) {} + + status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override; + status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override; + status_t setAsyncMode(bool async) override; + status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w, + uint32_t h, ::android::PixelFormat format, uint32_t usage, + FrameEventHistoryDelta* outTimestamps) override; + status_t detachBuffer(int slot) override; + status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) + override; + status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) + override; + status_t queueBuffer(int slot, + const QueueBufferInput& input, + QueueBufferOutput* output) override; + status_t cancelBuffer(int slot, const sp<Fence>& fence) override; + int query(int what, int* value) override; + status_t connect(const sp<IProducerListener>& listener, int api, + bool producerControlledByApp, QueueBufferOutput* output) override; + status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) + override; + status_t setSidebandStream(const sp<NativeHandle>& stream) override; + void allocateBuffers(uint32_t width, uint32_t height, + ::android::PixelFormat format, uint32_t usage) override; + status_t allowAllocation(bool allow) override; + status_t setGenerationNumber(uint32_t generationNumber) override; + String8 getConsumerName() const override; + status_t setSharedBufferMode(bool sharedBufferMode) override; + status_t setAutoRefresh(bool autoRefresh) override; + status_t setDequeueTimeout(nsecs_t timeout) override; + status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence, float outTransformMatrix[16]) override; + void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override; + status_t getUniqueId(uint64_t* outId) const override; +}; + +} // namespace utils +} // namespace V1_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BGRAPHICBUFFERPRODUCER_H diff --git a/libs/gui/include/gui/view/Surface.h b/libs/gui/include/gui/view/Surface.h new file mode 100644 index 0000000000..cc64fd45dd --- /dev/null +++ b/libs/gui/include/gui/view/Surface.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_VIEW_SURFACE_H +#define ANDROID_GUI_VIEW_SURFACE_H + +#include <utils/Errors.h> +#include <utils/StrongPointer.h> +#include <utils/String16.h> + +#include <binder/Parcelable.h> + +namespace android { + +class IGraphicBufferProducer; + +namespace view { + +/** + * A simple holder for an IGraphicBufferProducer, to match the managed-side + * android.view.Surface parcelable behavior. + * + * This implements android/view/Surface.aidl + * + * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly + * used in managed Binder calls. + */ +class Surface : public Parcelable { + public: + + String16 name; + sp<IGraphicBufferProducer> graphicBufferProducer; + + virtual status_t writeToParcel(Parcel* parcel) const override; + virtual status_t readFromParcel(const Parcel* parcel) override; + + // nameAlreadyWritten set to true by Surface.java, because it splits + // Parceling itself between managed and native code, so it only wants a part + // of the full parceling to happen on its native side. + status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const; + + // nameAlreadyRead set to true by Surface.java, because it splits + // Parceling itself between managed and native code, so it only wants a part + // of the full parceling to happen on its native side. + status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead); + + private: + + static String16 readMaybeEmptyString16(const Parcel* parcel); +}; + +} // namespace view +} // namespace android + +#endif // ANDROID_GUI_VIEW_SURFACE_H diff --git a/libs/gui/include/private/gui/ComposerService.h b/libs/gui/include/private/gui/ComposerService.h new file mode 100644 index 0000000000..50bd742b6a --- /dev/null +++ b/libs/gui/include/private/gui/ComposerService.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H +#define ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Singleton.h> +#include <utils/StrongPointer.h> + + +namespace android { + +// --------------------------------------------------------------------------- + +class ISurfaceComposer; + +// --------------------------------------------------------------------------- + +// This holds our connection to the composer service (i.e. SurfaceFlinger). +// If the remote side goes away, we will re-establish the connection. +// Users of this class should not retain the value from +// getComposerService() for an extended period. +// +// (It's not clear that using Singleton is useful here anymore.) +class ComposerService : public Singleton<ComposerService> +{ + sp<ISurfaceComposer> mComposerService; + sp<IBinder::DeathRecipient> mDeathObserver; + Mutex mLock; + + ComposerService(); + void connectLocked(); + void composerServiceDied(); + friend class Singleton<ComposerService>; +public: + + // Get a connection to the Composer Service. This will block until + // a connection is established. + static sp<ISurfaceComposer> getComposerService(); +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H diff --git a/libs/gui/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h new file mode 100644 index 0000000000..307c764702 --- /dev/null +++ b/libs/gui/include/private/gui/LayerState.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SF_LAYER_STATE_H +#define ANDROID_SF_LAYER_STATE_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/Errors.h> + +#include <ui/Region.h> +#include <ui/Rect.h> +#include <gui/IGraphicBufferProducer.h> + +namespace android { + +class Parcel; +class ISurfaceComposerClient; + +/* + * Used to communicate layer information between SurfaceFlinger and its clients. + */ +struct layer_state_t { + + + enum { + eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java + eLayerOpaque = 0x02, // SURFACE_OPAQUE + eLayerSecure = 0x80, // SECURE + }; + + enum { + ePositionChanged = 0x00000001, + eLayerChanged = 0x00000002, + eSizeChanged = 0x00000004, + eAlphaChanged = 0x00000008, + eMatrixChanged = 0x00000010, + eTransparentRegionChanged = 0x00000020, + eFlagsChanged = 0x00000040, + eLayerStackChanged = 0x00000080, + eCropChanged = 0x00000100, + eDeferTransaction = 0x00000200, + eFinalCropChanged = 0x00000400, + eOverrideScalingModeChanged = 0x00000800, + eGeometryAppliesWithResize = 0x00001000, + eReparentChildren = 0x00002000, + eDetachChildren = 0x00004000, + eRelativeLayerChanged = 0x00008000 + }; + + layer_state_t() + : what(0), + x(0), y(0), z(0), w(0), h(0), layerStack(0), + alpha(0), flags(0), mask(0), + reserved(0), crop(Rect::INVALID_RECT), + finalCrop(Rect::INVALID_RECT), frameNumber(0), + overrideScalingMode(-1) + { + matrix.dsdx = matrix.dtdy = 1.0f; + matrix.dsdy = matrix.dtdx = 0.0f; + } + + status_t write(Parcel& output) const; + status_t read(const Parcel& input); + + struct matrix22_t { + float dsdx{0}; + float dtdx{0}; + float dtdy{0}; + float dsdy{0}; + }; + sp<IBinder> surface; + uint32_t what; + float x; + float y; + int32_t z; + uint32_t w; + uint32_t h; + uint32_t layerStack; + float alpha; + uint8_t flags; + uint8_t mask; + uint8_t reserved; + matrix22_t matrix; + Rect crop; + Rect finalCrop; + sp<IBinder> barrierHandle; + sp<IBinder> reparentHandle; + uint64_t frameNumber; + int32_t overrideScalingMode; + + sp<IGraphicBufferProducer> barrierGbp; + + sp<IBinder> relativeLayerHandle; + + // non POD must be last. see write/read + Region transparentRegion; +}; + +struct ComposerState { + sp<ISurfaceComposerClient> client; + layer_state_t state; + status_t write(Parcel& output) const; + status_t read(const Parcel& input); +}; + +struct DisplayState { + + enum { + eOrientationDefault = 0, + eOrientation90 = 1, + eOrientation180 = 2, + eOrientation270 = 3, + eOrientationUnchanged = 4, + eOrientationSwapMask = 0x01 + }; + + enum { + eSurfaceChanged = 0x01, + eLayerStackChanged = 0x02, + eDisplayProjectionChanged = 0x04, + eDisplaySizeChanged = 0x08 + }; + + DisplayState(); + + uint32_t what; + sp<IBinder> token; + sp<IGraphicBufferProducer> surface; + uint32_t layerStack; + uint32_t orientation; + Rect viewport; + Rect frame; + uint32_t width, height; + status_t write(Parcel& output) const; + status_t read(const Parcel& input); +}; + +}; // namespace android + +#endif // ANDROID_SF_LAYER_STATE_H + diff --git a/libs/gui/include/private/gui/SyncFeatures.h b/libs/gui/include/private/gui/SyncFeatures.h new file mode 100644 index 0000000000..79fb75bcbe --- /dev/null +++ b/libs/gui/include/private/gui/SyncFeatures.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SYNC_FEATURES_H +#define ANDROID_GUI_SYNC_FEATURES_H + +#include <utils/Singleton.h> +#include <utils/String8.h> + + +namespace android { +// ---------------------------------------------------------------------------- + +class SyncFeatures : public Singleton<SyncFeatures> { + friend class Singleton<SyncFeatures>; + bool mHasNativeFenceSync; + bool mHasFenceSync; + bool mHasWaitSync; + String8 mString; + SyncFeatures(); + +public: + bool useNativeFenceSync() const; + bool useFenceSync() const; + bool useWaitSync() const; + String8 toString() const; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SYNC_FEATURES_H |