diff options
Diffstat (limited to 'include')
66 files changed, 2933 insertions, 1104 deletions
diff --git a/include/android/configuration.h b/include/android/configuration.h index 97d4c42..be00066 100644 --- a/include/android/configuration.h +++ b/include/android/configuration.h @@ -45,6 +45,7 @@ enum { ACONFIGURATION_DENSITY_XHIGH = 320, ACONFIGURATION_DENSITY_XXHIGH = 480, ACONFIGURATION_DENSITY_XXXHIGH = 640, + ACONFIGURATION_DENSITY_ANY = 0xfffe, ACONFIGURATION_DENSITY_NONE = 0xffff, ACONFIGURATION_KEYBOARD_ANY = 0x0000, diff --git a/include/android/input.h b/include/android/input.h index fead769..a660761 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -583,7 +583,7 @@ int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event); * and views. */ float AMotionEvent_getXOffset(const AInputEvent* motion_event); -/* Get the precision of the Y coordinates being reported. +/* Get the Y coordinate offset. * For touch events on the screen, this is the delta that was added to the raw * screen coordinates to adjust for the absolute position of the containing windows * and views. */ diff --git a/include/android/keycodes.h b/include/android/keycodes.h index b6a5f4c..75d0ab6 100644 --- a/include/android/keycodes.h +++ b/include/android/keycodes.h @@ -268,6 +268,41 @@ enum { AKEYCODE_MEDIA_AUDIO_TRACK = 222, AKEYCODE_SLEEP = 223, AKEYCODE_WAKEUP = 224, + AKEYCODE_PAIRING = 225, + AKEYCODE_MEDIA_TOP_MENU = 226, + AKEYCODE_11 = 227, + AKEYCODE_12 = 228, + AKEYCODE_LAST_CHANNEL = 229, + AKEYCODE_TV_DATA_SERVICE = 230, + AKEYCODE_VOICE_ASSIST = 231, + AKEYCODE_TV_RADIO_SERVICE = 232, + AKEYCODE_TV_TELETEXT = 233, + AKEYCODE_TV_NUMBER_ENTRY = 234, + AKEYCODE_TV_TERRESTRIAL_ANALOG = 235, + AKEYCODE_TV_TERRESTRIAL_DIGITAL = 236, + AKEYCODE_TV_SATELLITE = 237, + AKEYCODE_TV_SATELLITE_BS = 238, + AKEYCODE_TV_SATELLITE_CS = 239, + AKEYCODE_TV_SATELLITE_SERVICE = 240, + AKEYCODE_TV_NETWORK = 241, + AKEYCODE_TV_ANTENNA_CABLE = 242, + AKEYCODE_TV_INPUT_HDMI_1 = 243, + AKEYCODE_TV_INPUT_HDMI_2 = 244, + AKEYCODE_TV_INPUT_HDMI_3 = 245, + AKEYCODE_TV_INPUT_HDMI_4 = 246, + AKEYCODE_TV_INPUT_COMPOSITE_1 = 247, + AKEYCODE_TV_INPUT_COMPOSITE_2 = 248, + AKEYCODE_TV_INPUT_COMPONENT_1 = 249, + AKEYCODE_TV_INPUT_COMPONENT_2 = 250, + AKEYCODE_TV_INPUT_VGA_1 = 251, + AKEYCODE_TV_AUDIO_DESCRIPTION = 252, + AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253, + AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254, + AKEYCODE_TV_ZOOM_MODE = 255, + AKEYCODE_TV_CONTENTS_MENU = 256, + AKEYCODE_TV_MEDIA_CONTEXT_MENU = 257, + AKEYCODE_TV_TIMER_PROGRAMMING = 258, + AKEYCODE_HELP = 259 // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. diff --git a/include/android/sensor.h b/include/android/sensor.h index b71bccb..d58c460 100644 --- a/include/android/sensor.h +++ b/include/android/sensor.h @@ -74,6 +74,16 @@ enum { }; /* + * Sensor Reporting Modes. + */ +enum { + AREPORTING_MODE_CONTINUOUS = 0, + AREPORTING_MODE_ON_CHANGE = 1, + AREPORTING_MODE_ONE_SHOT = 2, + AREPORTING_MODE_SPECIAL_TRIGGER = 3 +}; + +/* * A few useful constants */ @@ -164,7 +174,9 @@ typedef struct ASensorEvent { uint64_t step_counter; } u64; }; - int32_t reserved1[4]; + + uint32_t flags; + int32_t reserved1[3]; } ASensorEvent; struct ASensorManager; @@ -198,11 +210,18 @@ int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list); /* * Returns the default sensor for the given type, or NULL if no sensor - * of that type exist. + * of that type exists. */ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type); /* + * Returns the default sensor with the given type and wakeUp properties or NULL if no sensor + * of this type and wakeUp properties exists. + */ +ASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager, int type, + bool wakeUp); + +/* * Creates a new sensor event queue and associate it with a looper. */ ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager, @@ -304,6 +323,16 @@ int ASensor_getFifoReservedEventCount(ASensor const* sensor); */ const char* ASensor_getStringType(ASensor const* sensor); +/* + * Returns the reporting mode for this sensor. One of AREPORTING_MODE_* constants. + */ +int ASensor_getReportingMode(ASensor const* sensor); + +/* + * Returns true if this is a wake up sensor, false otherwise. + */ +bool ASensor_isWakeUpSensor(ASensor const* sensor); + #ifdef __cplusplus }; #endif diff --git a/include/batteryservice/BatteryService.h b/include/batteryservice/BatteryService.h index 829061a..6211cf4 100644 --- a/include/batteryservice/BatteryService.h +++ b/include/batteryservice/BatteryService.h @@ -18,6 +18,7 @@ #define ANDROID_BATTERYSERVICE_H #include <binder/Parcel.h> +#include <sys/types.h> #include <utils/Errors.h> #include <utils/String8.h> @@ -43,6 +44,15 @@ enum { BATTERY_HEALTH_COLD = 7, // equals BatteryManager.BATTERY_HEALTH_COLD constant }; +// must be kept in sync with definitions in BatteryProperty.java +enum { + BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.CHARGE_COUNTER constant + BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.CURRENT_NOW constant + BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.CURRENT_AVG constant + BATTERY_PROP_CAPACITY = 4, // equals BatteryProperty.CAPACITY constant + BATTERY_PROP_ENERGY_COUNTER = 5, // equals BatteryProperty.ENERGY_COUNTER constant +}; + struct BatteryProperties { bool chargerAcOnline; bool chargerUsbOnline; @@ -52,8 +62,6 @@ struct BatteryProperties { bool batteryPresent; int batteryLevel; int batteryVoltage; - int batteryCurrentNow; - int batteryChargeCounter; int batteryTemperature; String8 batteryTechnology; @@ -61,6 +69,13 @@ struct BatteryProperties { status_t readFromParcel(Parcel* parcel); }; +struct BatteryProperty { + int64_t valueInt64; + + status_t writeToParcel(Parcel* parcel) const; + status_t readFromParcel(Parcel* parcel); +}; + }; // namespace android #endif // ANDROID_BATTERYSERVICE_H diff --git a/include/batteryservice/IBatteryPropertiesRegistrar.h b/include/batteryservice/IBatteryPropertiesRegistrar.h index 8d28b1d..eca075d 100644 --- a/include/batteryservice/IBatteryPropertiesRegistrar.h +++ b/include/batteryservice/IBatteryPropertiesRegistrar.h @@ -26,6 +26,7 @@ namespace android { enum { REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION, UNREGISTER_LISTENER, + GET_PROPERTY, }; class IBatteryPropertiesRegistrar : public IInterface { @@ -34,6 +35,7 @@ public: virtual void registerListener(const sp<IBatteryPropertiesListener>& listener) = 0; virtual void unregisterListener(const sp<IBatteryPropertiesListener>& listener) = 0; + virtual status_t getProperty(int id, struct BatteryProperty *val) = 0; }; class BnBatteryPropertiesRegistrar : public BnInterface<IBatteryPropertiesRegistrar> { diff --git a/include/binder/Binder.h b/include/binder/Binder.h index ba3ac4b..86628a0 100644 --- a/include/binder/Binder.h +++ b/include/binder/Binder.h @@ -17,6 +17,8 @@ #ifndef ANDROID_BINDER_H #define ANDROID_BINDER_H +#include <stdatomic.h> +#include <stdint.h> #include <binder/IBinder.h> // --------------------------------------------------------------------------- @@ -69,7 +71,7 @@ private: class Extras; - Extras* mExtras; + atomic_uintptr_t mExtras; // should be atomic<Extras *> void* mReserved0; }; diff --git a/include/binder/IBatteryStats.h b/include/binder/IBatteryStats.h new file mode 100644 index 0000000..7ddac57 --- /dev/null +++ b/include/binder/IBatteryStats.h @@ -0,0 +1,67 @@ +/* + * 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_IBATTERYSTATS_H +#define ANDROID_IBATTERYSTATS_H + +#include <binder/IInterface.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IBatteryStats : public IInterface +{ +public: + DECLARE_META_INTERFACE(BatteryStats); + + virtual void noteStartSensor(int uid, int sensor) = 0; + virtual void noteStopSensor(int uid, int sensor) = 0; + virtual void noteStartVideo(int uid) = 0; + virtual void noteStopVideo(int uid) = 0; + virtual void noteStartAudio(int uid) = 0; + virtual void noteStopAudio(int uid) = 0; + virtual void noteResetVideo() = 0; + virtual void noteResetAudio() = 0; + + enum { + NOTE_START_SENSOR_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + NOTE_STOP_SENSOR_TRANSACTION, + NOTE_START_VIDEO_TRANSACTION, + NOTE_STOP_VIDEO_TRANSACTION, + NOTE_START_AUDIO_TRANSACTION, + NOTE_STOP_AUDIO_TRANSACTION, + NOTE_RESET_VIDEO_TRANSACTION, + NOTE_RESET_AUDIO_TRANSACTION, + }; +}; + +// ---------------------------------------------------------------------- + +class BnBatteryStats : public BnInterface<IBatteryStats> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IBATTERYSTATS_H diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h index 8b84951..43b6543 100644 --- a/include/binder/IBinder.h +++ b/include/binder/IBinder.h @@ -81,14 +81,6 @@ public: Parcel* reply, uint32_t flags = 0) = 0; - /** - * This method allows you to add data that is transported through - * IPC along with your IBinder pointer. When implementing a Binder - * object, override it to write your desired data in to @a outData. - * You can then call getConstantData() on your IBinder to retrieve - * that data, from any process. You MUST return the number of bytes - * written in to the parcel (including padding). - */ class DeathRecipient : public virtual RefBase { public: diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h index 5bc123e..6e0c01b 100644 --- a/include/binder/IPCThreadState.h +++ b/include/binder/IPCThreadState.h @@ -107,7 +107,7 @@ private: static void threadDestructor(void *st); static void freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize, - const size_t* objects, size_t objectsSize, + const binder_size_t* objects, size_t objectsSize, void* cookie); const sp<ProcessState> mProcess; diff --git a/include/binder/MemoryDealer.h b/include/binder/MemoryDealer.h index 170f20d..aa415d5 100644 --- a/include/binder/MemoryDealer.h +++ b/include/binder/MemoryDealer.h @@ -34,7 +34,8 @@ class SimpleBestFitAllocator; class MemoryDealer : public RefBase { public: - MemoryDealer(size_t size, const char* name = 0); + MemoryDealer(size_t size, const char* name = 0, + uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ ); virtual sp<IMemory> allocate(size_t size); virtual void deallocate(size_t offset); diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index 98f20de..2ee99f8 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -23,6 +23,7 @@ #include <utils/String16.h> #include <utils/Vector.h> #include <utils/Flattenable.h> +#include <linux/binder.h> // --------------------------------------------------------------------------- namespace android { @@ -35,9 +36,8 @@ class ProcessState; class String8; class TextOutput; -struct flat_binder_object; // defined in support_p/binder_module.h - class Parcel { + friend class IPCThreadState; public: class ReadableBlob; class WritableBlob; @@ -81,7 +81,10 @@ public: void freeData(); - const size_t* objects() const; +private: + const binder_size_t* objects() const; + +public: size_t objectsCount() const; status_t errorCheck() const; @@ -94,7 +97,6 @@ public: status_t writeInt64(int64_t val); status_t writeFloat(float val); status_t writeDouble(double val); - status_t writeIntPtr(intptr_t val); status_t writeCString(const char* str); status_t writeString8(const String8& str); status_t writeString16(const String16& str); @@ -126,6 +128,11 @@ public: // will be closed once the parcel is destroyed. status_t writeDupFileDescriptor(int fd); + // Writes a raw fd and optional comm channel fd to the parcel as a ParcelFileDescriptor. + // A dup's of the fds are made, which will be closed once the parcel is destroyed. + // Null values are passed as -1. + status_t writeParcelFileDescriptor(int fd, int commChannel = -1); + // Writes a blob to the parcel. // If the blob is small, then it is stored in-place, otherwise it is // transferred by way of an anonymous shared memory region. @@ -185,6 +192,11 @@ public: // in the parcel, which you do not own -- use dup() to get your own copy. int readFileDescriptor() const; + // Reads a ParcelFileDescriptor from the parcel. Returns the raw fd as + // the result, and the optional comm channel fd in outCommChannel. + // Null values are returned as -1. + int readParcelFileDescriptor(int& outCommChannel) const; + // Reads a blob from the parcel. // The caller should call release() on the blob after reading its contents. status_t readBlob(size_t len, ReadableBlob* outBlob) const; @@ -194,19 +206,21 @@ public: // Explicitly close all file descriptors in the parcel. void closeFileDescriptors(); +private: typedef void (*release_func)(Parcel* parcel, const uint8_t* data, size_t dataSize, - const size_t* objects, size_t objectsSize, + const binder_size_t* objects, size_t objectsSize, void* cookie); - const uint8_t* ipcData() const; + uintptr_t ipcData() const; size_t ipcDataSize() const; - const size_t* ipcObjects() const; + uintptr_t ipcObjects() const; size_t ipcObjectsCount() const; void ipcSetDataReference(const uint8_t* data, size_t dataSize, - const size_t* objects, size_t objectsCount, + const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie); +public: void print(TextOutput& to, uint32_t flags = 0) const; private: @@ -219,6 +233,9 @@ private: status_t growData(size_t len); status_t restartWrite(size_t desired); status_t continueWrite(size_t desired); + status_t writePointer(uintptr_t val); + status_t readPointer(uintptr_t *pArg) const; + uintptr_t readPointer() const; void freeDataNoInit(); void initState(); void scanForFds() const; @@ -236,7 +253,7 @@ private: size_t mDataSize; size_t mDataCapacity; mutable size_t mDataPos; - size_t* mObjects; + binder_size_t* mObjects; size_t mObjectsSize; size_t mObjectsCapacity; mutable size_t mNextObjectHint; diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h index e63a0d0..3bc978d 100644 --- a/include/binder/ProcessState.h +++ b/include/binder/ProcessState.h @@ -27,11 +27,6 @@ // --------------------------------------------------------------------------- namespace android { -// Global variables -extern int mArgC; -extern const char* const* mArgV; -extern int mArgLen; - class IPCThreadState; class ProcessState : public virtual RefBase @@ -62,12 +57,6 @@ public: wp<IBinder> getWeakProxyForHandle(int32_t handle); void expungeHandle(int32_t handle, IBinder* binder); - void setArgs(int argc, const char* const argv[]); - int getArgC() const; - const char* const* getArgV() const; - - void setArgV0(const char* txt); - void spawnPooledThread(bool isMain); status_t setThreadPoolMaxThreadCount(size_t maxThreads); diff --git a/include/gui/BitTube.h b/include/gui/BitTube.h index d32df84..3ecac52 100644 --- a/include/gui/BitTube.h +++ b/include/gui/BitTube.h @@ -48,6 +48,9 @@ public: // get receive file-descriptor int getFd() const; + // get the send file-descriptor. + int getSendFd() const; + // send objects (sized blobs). All objects are guaranteed to be written or the call fails. template <typename T> static ssize_t sendObjects(const sp<BitTube>& tube, diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h new file mode 100644 index 0000000..5effd10 --- /dev/null +++ b/include/gui/BufferItem.h @@ -0,0 +1,103 @@ +/* + * 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 <EGL/egl.h> +#include <EGL/eglext.h> + +#include <gui/IGraphicBufferConsumer.h> + +#include <ui/Rect.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(); + operator IGraphicBufferConsumer::BufferItem() const; + + 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; + + // 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; + + // 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; +}; + +} // namespace android + +#endif diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h index 52edf17..5494ff1 100644 --- a/include/gui/BufferItemConsumer.h +++ b/include/gui/BufferItemConsumer.h @@ -44,6 +44,7 @@ class BufferItemConsumer: public ConsumerBase typedef BufferQueue::BufferItem BufferItem; + enum { DEFAULT_MAX_BUFFERS = -1 }; enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT }; enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE }; @@ -53,8 +54,8 @@ class BufferItemConsumer: public ConsumerBase // access at the same time. // controlledByApp tells whether this consumer is controlled by the // application. - BufferItemConsumer(const sp<BufferQueue>& bq, uint32_t consumerUsage, - int bufferCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS, + BufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, + uint32_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS, bool controlledByApp = false); virtual ~BufferItemConsumer(); diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index 408956b..3297b10 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -17,35 +17,29 @@ #ifndef ANDROID_GUI_BUFFERQUEUE_H #define ANDROID_GUI_BUFFERQUEUE_H -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#include <binder/IBinder.h> - -#include <gui/IConsumerListener.h> -#include <gui/IGraphicBufferAlloc.h> -#include <gui/IGraphicBufferProducer.h> +#include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferConsumer.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/IConsumerListener.h> -#include <ui/Fence.h> -#include <ui/GraphicBuffer.h> - -#include <utils/String8.h> -#include <utils/Vector.h> -#include <utils/threads.h> +// These are only required to keep other parts of the framework with incomplete +// dependencies building successfully +#include <gui/IGraphicBufferAlloc.h> namespace android { -// ---------------------------------------------------------------------------- -class BufferQueue : public BnGraphicBufferProducer, - public BnGraphicBufferConsumer, - private IBinder::DeathRecipient { +class BufferQueue { public: - enum { MIN_UNDEQUEUED_BUFFERS = 2 }; - enum { NUM_BUFFER_SLOTS = 32 }; - enum { NO_CONNECTED_API = 0 }; - enum { INVALID_BUFFER_SLOT = -1 }; - enum { STALE_BUFFER_SLOT = 1, NO_BUFFER_AVAILABLE, PRESENT_LATER }; + // 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 = IGraphicBufferConsumer::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. @@ -53,6 +47,7 @@ public: // for backward source compatibility typedef ::android::ConsumerListener ConsumerListener; + typedef IGraphicBufferConsumer::BufferItem BufferItem; // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak // reference to the actual consumer object. It forwards all calls to that @@ -69,503 +64,22 @@ public: virtual ~ProxyConsumerListener(); virtual void onFrameAvailable(); virtual void onBuffersReleased(); + virtual void onSidebandStreamChanged(); 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. - BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL); - virtual ~BufferQueue(); - - /* - * IBinder::DeathRecipient interface - */ - - virtual void binderDied(const wp<IBinder>& who); - - /* - * IGraphicBufferProducer interface - */ - - // Query native window attributes. The "what" values are enumerated in - // window.h (e.g. NATIVE_WINDOW_FORMAT). - virtual int query(int what, int* value); - - // setBufferCount updates the number of available buffer slots. If this - // method succeeds, buffer slots will be both unallocated and owned by - // the BufferQueue object (i.e. they are not owned by the producer or - // consumer). - // - // This will fail if the producer has dequeued any buffers, or if - // bufferCount is invalid. bufferCount must generally be a value - // between the minimum undequeued buffer count and NUM_BUFFER_SLOTS - // (inclusive). It may also be set to zero (the default) to indicate - // that the producer does not wish to set a value. The minimum value - // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, - // ...). - // - // This may only be called by the producer. The consumer will be told - // to discard buffers through the onBuffersReleased callback. - virtual status_t setBufferCount(int bufferCount); - - // 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); - - // 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 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. - // - // The pixel formats are enumerated in graphics.h, e.g. - // HAL_PIXEL_FORMAT_RGBA_8888. 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. - virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async, - uint32_t width, uint32_t height, uint32_t format, uint32_t usage); - - // 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 buf, - 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 void cancelBuffer(int buf, const sp<Fence>& fence); - - // 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<IBinder>& token, - int api, bool producerControlledByApp, QueueBufferOutput* output); - - // disconnect attempts to disconnect a producer API from the BufferQueue. - // 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. - // - // This method will fail if the the BufferQueue is not currently - // connected to the specified producer API. - virtual status_t disconnect(int api); - - /* - * IGraphicBufferConsumer interface - */ - - // acquireBuffer attempts to acquire ownership of the next pending buffer in - // the BufferQueue. If no buffer is pending then it returns -EINVAL. 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 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 *buffer, nsecs_t presentWhen); - - // 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 buf, uint64_t frameNumber, - EGLDisplay display, EGLSyncKHR fence, - const sp<Fence>& releaseFence); - - // 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. - virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp); - - // 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. - virtual status_t consumerDisconnect(); - - // getReleasedBuffers sets the value pointed to by slotMask 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(uint32_t* slotMask); - - // 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 w, uint32_t h); - - // setDefaultMaxBufferCount sets the default value for the maximum buffer - // count (the initial default is 2). If the producer has requested a - // buffer count using setBufferCount, the default buffer count will only - // take effect if the producer sets the count back to zero. - // - // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. - virtual status_t setDefaultMaxBufferCount(int bufferCount); - - // disableAsyncBuffer disables the extra buffer used in async mode - // (when both producer and consumer have set their "isControlledByApp" - // flag) and has dequeueBuffer() return WOULD_BLOCK instead. - // - // This can only be called before consumerConnect(). - virtual status_t disableAsyncBuffer(); - - // 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 - virtual void setConsumerName(const String8& name); - - // setDefaultBufferFormat allows the BufferQueue to create - // GraphicBuffers of a defaultFormat if no format is specified - // in dequeueBuffer. Formats are enumerated in graphics.h; the - // initial default is HAL_PIXEL_FORMAT_RGBA_8888. - virtual status_t setDefaultBufferFormat(uint32_t defaultFormat); - - // 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); - - // 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); - - // dump our state in a String - virtual void dump(String8& result, const char* prefix) const; - + static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer, + sp<IGraphicBufferConsumer>* outConsumer, + const sp<IGraphicBufferAlloc>& allocator = NULL); private: - // freeBufferLocked frees the GraphicBuffer and sync resources for the - // given slot. - void freeBufferLocked(int index); - - // freeAllBuffersLocked frees the GraphicBuffer and sync resources for - // all slots. - void freeAllBuffersLocked(); - - // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots - // that will be used if the producer does not override the buffer slot - // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. - // The initial default is 2. - status_t setDefaultMaxBufferCountLocked(int count); - - // getMinUndequeuedBufferCount 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 getMinUndequeuedBufferCount(bool async) const; - - // getMinBufferCountLocked returns the minimum number of buffers allowed - // given the current BufferQueue state. - // The async parameter tells whether we're in asynchronous mode. - int getMinMaxBufferCountLocked(bool async) const; - - // getMaxBufferCountLocked returns the maximum number of buffers that can - // be allocated at once. This value depends upon the following member - // variables: - // - // mDequeueBufferCannotBlock - // mMaxAcquiredBufferCount - // mDefaultMaxBufferCount - // mOverrideMaxBufferCount - // async parameter - // - // Any time one of these member variables is changed while a producer is - // connected, mDequeueCondition must be broadcast. - int getMaxBufferCountLocked(bool async) const; - - // stillTracking returns true iff the buffer item is still being tracked - // in one of the slots. - bool stillTracking(const BufferItem *item) const; - - struct BufferSlot { - - BufferSlot() - : mEglDisplay(EGL_NO_DISPLAY), - mBufferState(BufferSlot::FREE), - mRequestBufferCalled(false), - mFrameNumber(0), - mEglFence(EGL_NO_SYNC_KHR), - mAcquireCalled(false), - mNeedsCleanupOnRelease(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; - - // BufferState represents the different states in which a buffer slot - // can be. All slots are initially FREE. - enum BufferState { - // FREE indicates that the buffer is available to be dequeued - // by the producer. The buffer may be in use by the consumer for - // a finite time, so the buffer must not be modified until the - // associated fence is signaled. - // - // The slot is "owned" by BufferQueue. It transitions to DEQUEUED - // when dequeueBuffer is called. - FREE = 0, - - // 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 ready fence is signaled. - // - // The slot is "owned" by the producer. It can transition to - // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer). - DEQUEUED = 1, - - // 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). - QUEUED = 2, - - // 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 fence is signaled. - // - // The slot is "owned" by the consumer. It transitions to FREE - // when releaseBuffer is called. - ACQUIRED = 3 - }; - - // 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 this buffer needs to be cleaned up by the - // consumer. This is set when a buffer in ACQUIRED state is freed. - // It causes releaseBuffer to return STALE_BUFFER_SLOT. - bool mNeedsCleanupOnRelease; - }; - - // mSlots is the 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. - BufferSlot mSlots[NUM_BUFFER_SLOTS]; - - // mDefaultWidth holds the default width of allocated buffers. It is used - // in dequeueBuffer() if a width and height of zero is specified. - uint32_t mDefaultWidth; - - // mDefaultHeight holds the default height of allocated buffers. It is used - // in dequeueBuffer() if a width and height of zero is specified. - uint32_t mDefaultHeight; - - // 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 the setMaxAcquiredBufferCount method, but this may only be - // done when no producer is connected to the BufferQueue. - // - // This value is used to derive the value returned for the - // MIN_UNDEQUEUED_BUFFERS query by the producer. - int mMaxAcquiredBufferCount; - - // mDefaultMaxBufferCount is the default limit on the number of buffers - // that will be allocated at one time. This default limit is set by the - // consumer. The limit (as opposed to the default limit) may be - // overridden by the producer. - int mDefaultMaxBufferCount; - - // mOverrideMaxBufferCount is the limit on the number of buffers that will - // be allocated at one time. This value is set by the image producer by - // calling setBufferCount. The default is zero, which means the producer - // doesn't care about the number of buffers in the pool. In that case - // mDefaultMaxBufferCount is used as the limit. - int mOverrideMaxBufferCount; - - // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to - // allocate new GraphicBuffer objects. - sp<IGraphicBufferAlloc> mGraphicBufferAlloc; - - // 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; - - // mConsumerControlledByApp whether the connected consumer is controlled by the - // application. - bool mConsumerControlledByApp; - - // mDequeueBufferCannotBlock whether dequeueBuffer() isn't allowed to block. - // this flag is set during connect() when both consumer and producer are controlled - // by the application. - bool mDequeueBufferCannotBlock; - - // mUseAsyncBuffer whether an extra buffer is used in async mode to prevent - // dequeueBuffer() from ever blocking. - bool mUseAsyncBuffer; - - // mConnectedApi indicates the producer API that is currently connected - // to this BufferQueue. It defaults to NO_CONNECTED_API (= 0), and gets - // updated by the connect and disconnect methods. - int mConnectedApi; - - // mDequeueCondition condition used for dequeueBuffer in synchronous mode - mutable Condition mDequeueCondition; - - // mQueue is a FIFO of queued buffers used in synchronous mode - typedef Vector<BufferItem> Fifo; - Fifo mQueue; - - // mAbandoned 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 has been abandoned will - // return the NO_INIT error from all IGraphicBufferProducer methods - // capable of returning an error. - bool mAbandoned; - - // mConsumerName is a string used to identify the BufferQueue in log - // messages. It is set by the setConsumerName method. - String8 mConsumerName; - - // mMutex is the mutex used to prevent concurrent access to the member - // variables of BufferQueue objects. It must be locked whenever the - // member variables are accessed. - mutable Mutex mMutex; - - // mFrameCounter is the free running counter, incremented on every - // successful queueBuffer call, and buffer allocation. - uint64_t mFrameCounter; - - // 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; - - // mDefaultBufferFormat can be set so it will override - // the buffer format when it isn't specified in dequeueBuffer - uint32_t mDefaultBufferFormat; - - // mConsumerUsageBits contains flags the consumer wants for GraphicBuffers - uint32_t mConsumerUsageBits; - - // mTransformHint is used to optimize for screen rotations - uint32_t mTransformHint; - - // mConnectedProducerToken is used to set a binder death notification on the producer - sp<IBinder> mConnectedProducerToken; + BufferQueue(); // Create through createBufferQueue }; // ---------------------------------------------------------------------------- diff --git a/include/gui/BufferQueueConsumer.h b/include/gui/BufferQueueConsumer.h new file mode 100644 index 0000000..1912ed0 --- /dev/null +++ b/include/gui/BufferQueueConsumer.h @@ -0,0 +1,181 @@ +/* + * 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> + +namespace android { + +class BufferQueueCore; + +class BufferQueueConsumer : public BnGraphicBufferConsumer { + +public: + BufferQueueConsumer(const sp<BufferQueueCore>& core); + virtual ~BufferQueueConsumer(); + + // 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); + + // 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); + + // setDefaultMaxBufferCount sets the default value for the maximum buffer + // count (the initial default is 2). If the producer has requested a + // buffer count using setBufferCount, the default buffer count will only + // take effect if the producer sets the count back to zero. + // + // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. + virtual status_t setDefaultMaxBufferCount(int bufferCount); + + // disableAsyncBuffer disables the extra buffer used in async mode + // (when both producer and consumer have set their "isControlledByApp" + // flag) and has dequeueBuffer() return WOULD_BLOCK instead. + // + // This can only be called before connect(). + virtual status_t disableAsyncBuffer(); + + // 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 + virtual void setConsumerName(const String8& name); + + // setDefaultBufferFormat allows the BufferQueue to create + // GraphicBuffers of a defaultFormat if no format is specified + // in dequeueBuffer. Formats are enumerated in graphics.h; the + // initial default is HAL_PIXEL_FORMAT_RGBA_8888. + virtual status_t setDefaultBufferFormat(uint32_t defaultFormat); + + // 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); + + // 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. + virtual sp<NativeHandle> getSidebandStream() const; + + // dump our state in a String + virtual void dump(String8& result, const char* prefix) const; + + // 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/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h new file mode 100644 index 0000000..1050e3b --- /dev/null +++ b/include/gui/BufferQueueCore.h @@ -0,0 +1,253 @@ +/* + * 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/BufferQueueDefs.h> +#include <gui/BufferSlot.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> + +#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 BufferItem; +class IConsumerListener; +class IGraphicBufferAlloc; +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 = -1 }; // TODO: Extract from IGBC::BufferItem + + // 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 }; + + // The default API number used to indicate that no producer is connected + enum { NO_CONNECTED_API = 0 }; + + typedef Vector<BufferItem> Fifo; + + // BufferQueueCore manages a pool of gralloc memory slots to be used by + // producers and consumers. allocator is used to allocate all the needed + // gralloc buffers. + BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator = NULL); + virtual ~BufferQueueCore(); + +private: + // Dump our state in a string + void dump(String8& result, const char* prefix) 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(bool async) 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(bool async) const; + + // getMaxBufferCountLocked returns the maximum number of buffers that can be + // allocated at once. This value depends on the following member variables: + // + // mDequeueBufferCannotBlock + // mMaxAcquiredBufferCount + // mDefaultMaxBufferCount + // mOverrideMaxBufferCount + // async parameter + // + // Any time one of these member variables is changed while a producer is + // connected, mDequeueCondition must be broadcast. + int getMaxBufferCountLocked(bool async) const; + + // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots + // that will be used if the producer does not override the buffer slot + // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. The + // initial default is 2. + status_t setDefaultMaxBufferCountLocked(int count); + + // freeBufferLocked frees the GraphicBuffer and sync resources for the + // given slot. + void freeBufferLocked(int slot); + + // freeAllBuffersLocked frees the GraphicBuffer and sync resources for + // all slots. + void freeAllBuffersLocked(); + + // stillTracking returns true iff the buffer item is still being tracked + // in one of the slots. + bool stillTracking(const BufferItem* item) const; + + // waitWhileAllocatingLocked blocks until mIsAllocating is false. + void waitWhileAllocatingLocked() const; + + // mAllocator is the connection to SurfaceFlinger that is used to allocate + // new GraphicBuffer objects. + sp<IGraphicBufferAlloc> mAllocator; + + // 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; + + // 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; + + // mConnectedProducerToken is used to set a binder death notification on + // the producer. + 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; + + // mOverrideMaxBufferCount is the limit on the number of buffers that will + // be allocated at one time. This value is set by the producer by calling + // setBufferCount. The default is 0, which means that the producer doesn't + // care about the number of buffers in the pool. In that case, + // mDefaultMaxBufferCount is used as the limit. + int mOverrideMaxBufferCount; + + // mDequeueCondition is a condition variable used for dequeueBuffer in + // synchronous mode. + mutable Condition mDequeueCondition; + + // mUseAsyncBuffer indicates whether an extra buffer is used in async mode + // to prevent dequeueBuffer from blocking. + bool mUseAsyncBuffer; + + // 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. + uint32_t mDefaultBufferFormat; + + // mDefaultWidth holds the default width of allocated buffers. It is used + // in dequeueBuffer if a width and height of 0 are specified. + int mDefaultWidth; + + // mDefaultHeight holds the default height of allocated buffers. It is used + // in dequeueBuffer if a width and height of 0 are specified. + int mDefaultHeight; + + // mDefaultMaxBufferCount is the default limit on the number of buffers that + // will be allocated at one time. This default limit is set by the consumer. + // The limit (as opposed to the default limit) may be overriden by the + // producer. + int mDefaultMaxBufferCount; + + // 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; + + // 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; +}; // class BufferQueueCore + +} // namespace android + +#endif diff --git a/include/gui/BufferQueueDefs.h b/include/gui/BufferQueueDefs.h new file mode 100644 index 0000000..83e9580 --- /dev/null +++ b/include/gui/BufferQueueDefs.h @@ -0,0 +1,35 @@ +/* + * 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> + +namespace android { + class BufferQueueCore; + + namespace BufferQueueDefs { + // 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 = 64 }; + + typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; + } // namespace BufferQueueDefs +} // namespace android + +#endif diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h new file mode 100644 index 0000000..3fc5de2 --- /dev/null +++ b/include/gui/BufferQueueProducer.h @@ -0,0 +1,204 @@ +/* + * 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 { + +class BufferSlot; + +class BufferQueueProducer : public BnGraphicBufferProducer, + private IBinder::DeathRecipient { +public: + friend class BufferQueue; // Needed to access binderDied + + BufferQueueProducer(const sp<BufferQueueCore>& core); + virtual ~BufferQueueProducer(); + + // 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); + + // setBufferCount updates the number of available buffer slots. If this + // method succeeds, buffer slots will be both unallocated and owned by + // the BufferQueue object (i.e. they are not owned by the producer or + // consumer). + // + // This will fail if the producer has dequeued any buffers, or if + // bufferCount is invalid. bufferCount must generally be a value + // between the minimum undequeued buffer count (exclusive) and NUM_BUFFER_SLOTS + // (inclusive). It may also be set to zero (the default) to indicate + // that the producer does not wish to set a value. The minimum value + // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, + // ...). + // + // This may only be called by the producer. The consumer will be told + // to discard buffers through the onBuffersReleased callback. + virtual status_t setBufferCount(int bufferCount); + + // 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. + // + // The pixel formats are enumerated in graphics.h, e.g. + // HAL_PIXEL_FORMAT_RGBA_8888. 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. + virtual status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence, bool async, + uint32_t width, uint32_t height, uint32_t format, uint32_t usage); + + // 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 void 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); + + // disconnect attempts to disconnect a producer API from the BufferQueue. + // 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. + // + // This method will fail if the the BufferQueue is not currently + // connected to the specified producer API. + virtual status_t disconnect(int 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(bool async, uint32_t width, uint32_t height, + uint32_t format, uint32_t usage); + +private: + // This is required by the IBinder::DeathRecipient interface + virtual void binderDied(const wp<IBinder>& who); + + // 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. + status_t waitForFreeSlotThenRelock(const char* caller, bool async, + int* found, status_t* returnFlags) 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; + +}; // class BufferQueueProducer + +} // namespace android + +#endif diff --git a/include/gui/BufferSlot.h b/include/gui/BufferSlot.h new file mode 100644 index 0000000..6085e11 --- /dev/null +++ b/include/gui/BufferSlot.h @@ -0,0 +1,142 @@ +/* + * 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; + +struct BufferSlot { + + BufferSlot() + : mEglDisplay(EGL_NO_DISPLAY), + mBufferState(BufferSlot::FREE), + mRequestBufferCalled(false), + mFrameNumber(0), + mEglFence(EGL_NO_SYNC_KHR), + mAcquireCalled(false), + mNeedsCleanupOnRelease(false), + mAttachedByConsumer(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; + + // BufferState represents the different states in which a buffer slot + // can be. All slots are initially FREE. + enum BufferState { + // FREE indicates that the buffer is available to be dequeued + // by the producer. The buffer may be in use by the consumer for + // a finite time, so the buffer must not be modified until the + // associated fence is signaled. + // + // The slot is "owned" by BufferQueue. It transitions to DEQUEUED + // when dequeueBuffer is called. + FREE = 0, + + // 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 ready fence is signaled. + // + // The slot is "owned" by the producer. It can transition to + // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer). + DEQUEUED = 1, + + // 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). + QUEUED = 2, + + // 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 fence is signaled. + // + // The slot is "owned" by the consumer. It transitions to FREE + // when releaseBuffer is called. + ACQUIRED = 3 + }; + + static const char* bufferStateName(BufferState state); + + // 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 this buffer needs to be cleaned up by the + // consumer. This is set when a buffer in ACQUIRED state is freed. + // It causes releaseBuffer to return STALE_BUFFER_SLOT. + bool mNeedsCleanupOnRelease; + + // Indicates whether the buffer was attached on the consumer side. + // If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when dequeued + // to prevent the producer from using a stale cached buffer. + bool mAttachedByConsumer; +}; + +} // namespace android + +#endif diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h index fb21185..100bb26 100644 --- a/include/gui/ConsumerBase.h +++ b/include/gui/ConsumerBase.h @@ -101,11 +101,14 @@ protected: // Implementation of the IConsumerListener interface. These // calls are used to notify the ConsumerBase of asynchronous events in the - // BufferQueue. These 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. + // BufferQueue. The onFrameAvailable 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(); virtual void onBuffersReleased(); + virtual void onSidebandStreamChanged(); // freeBufferLocked frees up the given buffer slot. If the slot has been // initialized this will release the reference to the GraphicBuffer in that diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h index f8267bf..a4718b9 100644 --- a/include/gui/DisplayEventReceiver.h +++ b/include/gui/DisplayEventReceiver.h @@ -49,7 +49,7 @@ public: struct Header { uint32_t type; uint32_t id; - nsecs_t timestamp; + nsecs_t timestamp __attribute__((aligned(8))); }; struct VSync { diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h index a5fdfb9..f91fe46 100644 --- a/include/gui/GLConsumer.h +++ b/include/gui/GLConsumer.h @@ -52,28 +52,17 @@ class String8; * This class was previously called SurfaceTexture. */ class GLConsumer : public ConsumerBase { -protected: - enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES public: + enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; - // GLConsumer constructs a new GLConsumer object. tex indicates the - // name of the OpenGL ES texture to which images are to be streamed. - // allowSynchronousMode specifies whether or not synchronous mode can be - // enabled. 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 custom bufferQueue can be specified - // if behavior for queue/dequeue/connect etc needs to be customized. - // Otherwise a default BufferQueue will be created and used. - // - // For legacy reasons, 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. + // 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 @@ -81,9 +70,24 @@ public: // 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 = TEXTURE_EXTERNAL, - bool useFenceSync = true, bool isControlledByApp = false); + 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. @@ -227,7 +231,7 @@ public: protected: // abandonLocked overrides the ConsumerBase method to clear - // mCurrentTextureBuf in addition to the ConsumerBase behavior. + // mCurrentTextureImage in addition to the ConsumerBase behavior. virtual void abandonLocked(); // dumpLocked overrides the ConsumerBase method to dump GLConsumer- @@ -258,7 +262,7 @@ protected: status_t updateAndReleaseLocked(const BufferQueue::BufferItem& item); // Binds mTexName and the current buffer to mTexTarget. Uses - // mCurrentTexture if it's set, mCurrentTextureBuf if not. If the + // mCurrentTexture if it's set, mCurrentTextureImage if not. If the // bind succeeds, this calls doGLFenceWait. status_t bindTextureImageLocked(); @@ -271,11 +275,59 @@ protected: status_t checkAndUpdateEglStateLocked(bool contextCheck = false); private: - // createImage creates a new EGLImage from a GraphicBuffer. - EGLImageKHR createImage(EGLDisplay dpy, - const sp<GraphicBuffer>& graphicBuffer, const Rect& crop); + // 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; - // freeBufferLocked frees up the given buffer slot. If the slot has been + // 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. // @@ -285,7 +337,7 @@ private: // 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. - // mCurrentTextureBuf must not be NULL. + // mCurrentTextureImage must not be NULL. void computeCurrentTransformMatrixLocked(); // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command @@ -299,13 +351,6 @@ private: // before the outstanding accesses have completed. status_t syncForReleaseLocked(EGLDisplay dpy); - // Normally, when we bind a buffer to a texture target, we bind a buffer - // that is referenced by an entry in mEglSlots. In some situations we - // have a buffer in mCurrentTextureBuf, but no corresponding entry for - // it in our slot array. bindUnslottedBuffer handles that situation by - // binding the buffer without touching the EglSlots. - status_t bindUnslottedBufferLocked(EGLDisplay dpy); - // returns a graphic buffer used when the texture image has been released static sp<GraphicBuffer> getDebugTexImageBuffer(); @@ -315,10 +360,10 @@ private: // consume buffers as hardware textures. static const uint32_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; - // mCurrentTextureBuf is the graphic buffer of the current texture. It's + // 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<GraphicBuffer> mCurrentTextureBuf; + sp<EglImage> mCurrentTextureImage; // mCurrentCrop is the crop rectangle that applies to the current texture. // It gets set each time updateTexImage is called. @@ -378,17 +423,10 @@ private: // EGLSlot contains the information and object references that // GLConsumer maintains about a BufferQueue buffer slot. struct EglSlot { - EglSlot() - : mEglImage(EGL_NO_IMAGE_KHR), - mEglFence(EGL_NO_SYNC_KHR) { - } + EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {} // mEglImage is the EGLImage created from mGraphicBuffer. - EGLImageKHR mEglImage; - - // mCropRect is the crop rectangle passed to EGL when mEglImage was - // created. - Rect mCropRect; + 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 @@ -440,6 +478,7 @@ private: // mReleasedTexImageBuffer is a dummy buffer used when in single buffer // mode and releaseTexImage() has been called static sp<GraphicBuffer> sReleasedTexImageBuffer; + sp<EglImage> mReleasedTexImage; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/IConsumerListener.h b/include/gui/IConsumerListener.h index ac2f9bb..260099e 100644 --- a/include/gui/IConsumerListener.h +++ b/include/gui/IConsumerListener.h @@ -57,6 +57,12 @@ public: // 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 */ }; diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h index 0e35f13..15f51fe 100644 --- a/include/gui/IGraphicBufferConsumer.h +++ b/include/gui/IGraphicBufferConsumer.h @@ -27,12 +27,16 @@ #include <binder/IInterface.h> #include <ui/Rect.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> + namespace android { // ---------------------------------------------------------------------------- -class IConsumerListener; -class GraphicBuffer; class Fence; +class GraphicBuffer; +class IConsumerListener; +class NativeHandle; class IGraphicBufferConsumer : public IInterface { @@ -48,6 +52,7 @@ public: 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(); @@ -63,13 +68,17 @@ public: 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. + // 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 @@ -79,7 +88,7 @@ public: // mFrameNumber is the number of the queued frame for this slot. uint64_t mFrameNumber; - // mBuf is the slot index of this buffer + // mBuf is the slot index of this buffer (default INVALID_BUFFER_SLOT). int mBuf; // mIsDroppable whether this buffer was queued with the @@ -97,21 +106,72 @@ public: bool mTransformToDisplayInverse; }; + 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 -EINVAL. If a - // buffer is successfully acquired, the information about the buffer is - // returned in BufferItem. If the buffer returned had previously been + // 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 nonzero, it indicates the time when the buffer will + // 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. - virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) = 0; + // + // 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) = 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 buffer + // queue. 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 + // * 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 @@ -125,6 +185,18 @@ public: // // 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; @@ -137,24 +209,38 @@ public: // the application. // // consumer may not be NULL. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue 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 mask - // indicating which buffer slots have been released by the BufferQueue - // but have not yet been released by the consumer. + // 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 have not yet been released by the consumer. // // This should be called from the onBuffersReleased() callback. - virtual status_t getReleasedBuffers(uint32_t* slotMask) = 0; + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue 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; // setDefaultMaxBufferCount sets the default value for the maximum buffer @@ -163,6 +249,9 @@ public: // take effect if the producer sets the count back to zero. // // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - bufferCount was out of range (see above). virtual status_t setDefaultMaxBufferCount(int bufferCount) = 0; // disableAsyncBuffer disables the extra buffer used in async mode @@ -170,11 +259,20 @@ public: // flag) and has dequeueBuffer() return WOULD_BLOCK instead. // // This can only be called before consumerConnect(). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * INVALID_OPERATION - attempting to call this after consumerConnect. virtual status_t disableAsyncBuffer() = 0; // 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. + // + // maxAcquiredBuffers must be (inclusive) between 1 and MAX_MAX_ACQUIRED_BUFFERS. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - maxAcquiredBuffers was out of range (see above). + // * INVALID_OPERATION - attempting to call this after a producer connected. virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0; // setConsumerName sets the name used in logging @@ -184,18 +282,27 @@ public: // GraphicBuffers of a defaultFormat if no format is specified // in dequeueBuffer. Formats are enumerated in graphics.h; the // initial default is HAL_PIXEL_FORMAT_RGBA_8888. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) = 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; // 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 sp<NativeHandle> getSidebandStream() const = 0; + // dump state into a string virtual void dump(String8& result, const char* prefix) const = 0; diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h index 342ba08..4e9e810 100644 --- a/include/gui/IGraphicBufferProducer.h +++ b/include/gui/IGraphicBufferProducer.h @@ -32,6 +32,8 @@ namespace android { // ---------------------------------------------------------------------------- +class IProducerListener; +class NativeHandle; class Surface; /* @@ -54,7 +56,11 @@ public: DECLARE_META_INTERFACE(GraphicBufferProducer); 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, }; @@ -63,60 +69,222 @@ public: // 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. + // * 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; // setBufferCount sets the number of buffer slots available. Calling this // will also cause all buffer slots to be emptied. The caller should empty // its mirrored copy of the buffer slots when calling this method. + // + // This function should not be called when there are any dequeued buffer + // slots, doing so will result in a BAD_VALUE error returned. + // + // The buffer count should be at most NUM_BUFFER_SLOTS (inclusive), but at least + // the minimum undequeued buffer count (exclusive). The minimum value + // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS). + // In particular the range is (minUndequeudBuffers, NUM_BUFFER_SLOTS]. + // + // The buffer count may also be set to 0 (the default), to indicate that + // the producer does not wish to set a value. + // + // 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 has one or more buffers dequeued virtual status_t setBufferCount(int bufferCount) = 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. If the slot is empty the client - // should call requestBuffer to assign a new buffer to that slot. The client - // is expected to either call cancelBuffer on the dequeued slot or to fill - // in the contents of its associated buffer contents and call queueBuffer. - // If dequeueBuffer return BUFFER_NEEDS_REALLOCATION, the client is + // 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 NULL, the buffer may be written + // fence signals. If the fence is Fence::NO_FENCE, the buffer may be written // immediately. // - // The async parameter sets whether we're in asynchrnous mode for this - // deququeBuffer() call. - virtual status_t dequeueBuffer(int *slot, sp<Fence>* fence, bool async, + // The async parameter sets whether we're in asynchronous mode for this + // dequeueBuffer() call. + // + // 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. + // + // The pixel formats are enumerated in <graphics.h>, e.g. + // HAL_PIXEL_FORMAT_RGBA_8888. 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. + // * 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. + // + // 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, bool async, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 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. + // * 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. + // * 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. + // * BAD_VALUE - outSlot or buffer were NULL or invalid combination of + // async mode and buffer count override. + // * 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. + 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. In addition, a timestamp must be provided by the - // client for this buffer. The timestamp is measured in nanoseconds, and - // must be monotonically increasing. Its other properties (zero point, etc) + // 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 async parameter sets whether we're queuing a buffer in asynchronous mode. + // The slot must be in the range of [0, NUM_BUFFER_SLOTS). // - // outWidth, outHeight and outTransform are filled with the default width - // and height of the window and current transform applied to buffers, - // respectively. + // 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. + // * 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>; inline QueueBufferInput(const Parcel& parcel); + // timestamp - a monotonically increasing value in nanoseconds + // isAutoTimestamp - if the timestamp was synthesized at queue time + // 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> + // async - if the buffer is queued in asynchronous mode + // 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). inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp, const Rect& crop, int scalingMode, uint32_t transform, bool async, - const sp<Fence>& fence) + const sp<Fence>& fence, uint32_t sticky = 0) : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), crop(crop), - scalingMode(scalingMode), transform(transform), async(async), - fence(fence) { } + scalingMode(scalingMode), transform(transform), stickyTransform(sticky), + async(async), fence(fence) { } inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp, Rect* outCrop, int* outScalingMode, uint32_t* outTransform, - bool* outAsync, sp<Fence>* outFence) const { + bool* outAsync, sp<Fence>* outFence, + uint32_t* outStickyTransform = NULL) const { *outTimestamp = timestamp; *outIsAutoTimestamp = bool(isAutoTimestamp); *outCrop = crop; @@ -124,6 +292,9 @@ public: *outTransform = transform; *outAsync = bool(async); *outFence = fence; + if (outStickyTransform != NULL) { + *outStickyTransform = stickyTransform; + } } // Flattenable protocol @@ -138,13 +309,19 @@ public: Rect crop; int scalingMode; uint32_t transform; + uint32_t stickyTransform; int async; sp<Fence> fence; }; // QueueBufferOutput must be a POD structure - struct QueueBufferOutput { + struct __attribute__ ((__packed__)) QueueBufferOutput { inline QueueBufferOutput() { } + // outWidth - filled with default width applied to the buffer + // outHeight - filled with default height applied to the buffer + // outTransformHint - filled with default transform applied to the buffer + // outNumPendingBuffers - num buffers queued that haven't yet been acquired + // (counting the currently queued buffer) inline void deflate(uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransformHint, @@ -174,25 +351,57 @@ public: // 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 buffer will not be overwritten until the fence signals. The fence + // will usually be the one obtained from dequeueBuffer. virtual void cancelBuffer(int slot, const sp<Fence>& fence) = 0; // query retrieves some information for this surface - // 'what' tokens allowed are that of android_natives.h + // '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. + // 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. // - // outWidth, outHeight and outTransform are filled with the default width - // and height of the window and current transform applied to buffers, - // respectively. The token needs to be any binder object that lives in the - // producer process -- it is solely used for obtaining a death notification - // when the producer is killed. - virtual status_t connect(const sp<IBinder>& token, + // 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. + // * 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; // disconnect attempts to disconnect a client API from the @@ -203,7 +412,43 @@ public: // // This method will fail if the the IGraphicBufferProducer is not currently // connected to the specified client API. + // + // The api should be one of the NATIVE_WINDOW_API_* values in <window.h> + // + // 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: + // * 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) = 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(bool async, uint32_t width, uint32_t height, + uint32_t format, uint32_t usage) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/IProducerListener.h b/include/gui/IProducerListener.h new file mode 100644 index 0000000..3848a6c --- /dev/null +++ b/include/gui/IProducerListener.h @@ -0,0 +1,67 @@ +/* + * 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 +}; + +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); +}; + +class DummyProducerListener : public BnProducerListener +{ +public: + virtual void onBufferReleased() {} +}; + +} // namespace android + +#endif diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 5c3c99c..3ffc67e 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -22,9 +22,12 @@ #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 <gui/IGraphicBufferAlloc.h> @@ -36,8 +39,10 @@ namespace android { class ComposerState; class DisplayState; class DisplayInfo; +class DisplayStatInfo; class IDisplayEventConnection; class IMemoryHeap; +class Rect; /* * This class defines the Binder IPC interface for accessing various @@ -58,6 +63,13 @@ public: eDisplayIdHdmi = 1 }; + enum Rotation { + eRotateNone = 0, + eRotate90 = 1, + eRotate180 = 2, + eRotate270 = 3 + }; + /* create connection with surface flinger, requires * ACCESS_SURFACE_FLINGER permission */ @@ -100,27 +112,52 @@ public: virtual bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& surface) const = 0; - /* triggers screen off and waits for it to complete - * requires ACCESS_SURFACE_FLINGER permission. - */ - virtual void blank(const sp<IBinder>& display) = 0; - - /* triggers screen on and waits for it to complete + /* 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 unblank(const sp<IBinder>& display) = 0; + virtual void setPowerMode(const sp<IBinder>& display, int mode) = 0; - /* returns information about a display + /* returns information for each configuration of the given display * intended to be used to get information about built-in displays */ - virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 0; + 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; /* 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, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ) = 0; + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_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; }; // ---------------------------------------------------------------------------- @@ -139,11 +176,15 @@ public: GET_BUILT_IN_DISPLAY, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, - BLANK, - UNBLANK, - GET_DISPLAY_INFO, + 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, }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index cb9816f..bb79bd0 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -25,6 +25,7 @@ #include <binder/IInterface.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> namespace android { @@ -46,6 +47,7 @@ public: eOpaque = 0x00000400, eProtectedByApp = 0x00000800, eProtectedByDRM = 0x00001000, + eCursorWindow = 0x00002000, eFXSurfaceNormal = 0x00000000, eFXSurfaceDim = 0x00020000, @@ -65,6 +67,16 @@ public: * 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; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h index 033b262..28a08e2 100644 --- a/include/gui/Sensor.h +++ b/include/gui/Sensor.h @@ -71,6 +71,10 @@ public: int32_t getFifoMaxEventCount() const; const String8& getStringType() const; const String8& getRequiredPermission() const; + int32_t getMaxDelay() const; + int32_t getFlags() const; + bool isWakeUpSensor() const; + int32_t getReportingMode() const; // LightFlattenable protocol inline bool isFixedSize() const { return false; } @@ -93,6 +97,8 @@ private: int32_t mFifoMaxEventCount; String8 mStringType; String8 mRequiredPermission; + int32_t mMaxDelay; + int32_t mFlags; static void flattenString8(void*& buffer, size_t& size, const String8& string8); static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8); }; diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h index 0bfc7a0..02b3d38 100644 --- a/include/gui/SensorEventQueue.h +++ b/include/gui/SensorEventQueue.h @@ -27,7 +27,7 @@ #include <gui/BitTube.h> // ---------------------------------------------------------------------------- - +#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31) struct ALooper; struct ASensorEvent; @@ -75,7 +75,8 @@ public: int reservedFlags) const; status_t disableSensor(int32_t handle) const; status_t flush() const; - + // Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK. + void sendAck(const ASensorEvent* events, int count); private: sp<Looper> getLooper() const; sp<ISensorEventConnection> mSensorEventConnection; @@ -85,6 +86,7 @@ private: ASensorEvent* mRecBuffer; size_t mAvailable; size_t mConsumed; + uint32_t mNumAcksToSend; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/StreamSplitter.h b/include/gui/StreamSplitter.h new file mode 100644 index 0000000..f927953 --- /dev/null +++ b/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(); + + // 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/include/gui/Surface.h b/include/gui/Surface.h index 6f8a97c..f2cf018 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -78,6 +78,29 @@ public: 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(); + protected: virtual ~Surface(); @@ -115,12 +138,14 @@ private: 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); protected: virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); @@ -140,6 +165,7 @@ protected: virtual int setBuffersFormat(int format); virtual int setScalingMode(int mode); virtual int setBuffersTransform(int transform); + virtual int setBuffersStickyTransform(int transform); virtual int setBuffersTimestamp(int64_t timestamp); virtual int setCrop(Rect const* rect); virtual int setUsage(uint32_t reqUsage); @@ -208,6 +234,12 @@ private: // 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; diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index e982bcd..4cbfc09 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -28,6 +28,7 @@ #include <utils/SortedVector.h> #include <utils/threads.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> #include <gui/CpuConsumer.h> @@ -65,14 +66,24 @@ public: status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient, void* cookie = NULL, uint32_t flags = 0); - // Get information about a display - static status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info); + // Get a list of supported configurations for a given display + static status_t getDisplayConfigs(const sp<IBinder>& display, + Vector<DisplayInfo>* configs); - /* triggers screen off and waits for it to complete */ - static void blankDisplay(const sp<IBinder>& display); + // Get the DisplayInfo for the currently-active configuration + static status_t getDisplayInfo(const sp<IBinder>& display, + DisplayInfo* info); - /* triggers screen on and waits for it to complete */ - static void unblankDisplay(const sp<IBinder>& display); + // 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); + + /* 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 @@ -125,10 +136,17 @@ public: status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); 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 void setDisplaySurface(const sp<IBinder>& token, const 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. @@ -160,15 +178,18 @@ private: 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, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ); + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform); private: mutable sp<CpuConsumer> mCpuConsumer; - mutable sp<BufferQueue> mBufferQueue; + mutable sp<IGraphicBufferProducer> mProducer; CpuConsumer::LockedBuffer mBuffer; bool mHaveBuffer; @@ -176,13 +197,22 @@ public: ScreenshotClient(); ~ScreenshotClient(); - // frees the previous screenshot and capture a new one - status_t update(const sp<IBinder>& display); + // 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, - uint32_t reqWidth, uint32_t reqHeight); + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform); status_t update(const sp<IBinder>& display, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ); + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform, uint32_t rotation); sp<CpuConsumer> getCpuConsumer() const; diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index f27754c..84fb9f9 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -24,6 +24,7 @@ #include <utils/RefBase.h> #include <utils/threads.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> #include <ui/Region.h> @@ -52,10 +53,10 @@ public: static bool isSameSurface( const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); - + // release surface data from java void clear(); - + status_t setLayerStack(int32_t layerStack); status_t setLayer(int32_t layer); status_t setPosition(float x, float y); @@ -73,6 +74,9 @@ public: sp<Surface> getSurface() const; + status_t clearLayerFrameStats() const; + status_t getLayerFrameStats(FrameStats* outStats) const; + private: // can't be copied SurfaceControl& operator = (SurfaceControl& rhs); @@ -90,7 +94,7 @@ private: status_t validate() const; void destroy(); - + sp<SurfaceComposerClient> mClient; sp<IBinder> mHandle; sp<IGraphicBufferProducer> mGraphicBufferProducer; diff --git a/include/input/Input.h b/include/input/Input.h index df6921a..09419c9 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -72,7 +72,7 @@ enum { * Constants for LEDs. Hidden from the API since we don't actually expose a way to interact * with LEDs to developers * - * NOTE: If you add LEDs here, you must also add them to KeycodeLabels.h + * NOTE: If you add LEDs here, you must also add them to InputEventLabels.h */ ALED_NUM_LOCK = 0x00, @@ -152,18 +152,12 @@ class Parcel; */ enum { /* These flags originate in RawEvents and are generally set in the key map. - * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */ + * NOTE: If you want a flag to be able to set in a keylayout file, then you must add it to + * InputEventLabels.h as well. */ POLICY_FLAG_WAKE = 0x00000001, - POLICY_FLAG_WAKE_DROPPED = 0x00000002, - POLICY_FLAG_SHIFT = 0x00000004, - POLICY_FLAG_CAPS_LOCK = 0x00000008, - POLICY_FLAG_ALT = 0x00000010, - POLICY_FLAG_ALT_GR = 0x00000020, - POLICY_FLAG_MENU = 0x00000040, - POLICY_FLAG_LAUNCHER = 0x00000080, - POLICY_FLAG_VIRTUAL = 0x00000100, - POLICY_FLAG_FUNCTION = 0x00000200, + POLICY_FLAG_VIRTUAL = 0x00000002, + POLICY_FLAG_FUNCTION = 0x00000004, POLICY_FLAG_RAW_MASK = 0x0000ffff, @@ -198,10 +192,10 @@ enum { * Pointer coordinate data. */ struct PointerCoords { - enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64 + enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 128 // Bitfield of axes that are present in this structure. - uint64_t bits; + uint64_t bits __attribute__((aligned(8))); // Values of axes that are stored in this structure packed in order by axis id // for each axis that is present in the structure according to 'bits'. @@ -318,13 +312,8 @@ public: inline nsecs_t getEventTime() const { return mEventTime; } - // Return true if this event may have a default action implementation. - static bool hasDefaultAction(int32_t keyCode); - bool hasDefaultAction() const; - - // Return true if this event represents a system key. - static bool isSystemKey(int32_t keyCode); - bool isSystemKey() const; + static const char* getLabel(int32_t keyCode); + static int32_t getKeyCodeFromLabel(const char* label); void initialize( int32_t deviceId, @@ -584,6 +573,9 @@ public: return mSamplePointerCoords.array(); } + static const char* getLabel(int32_t axis); + static int32_t getAxisFromLabel(const char* label); + protected: int32_t mAction; int32_t mFlags; diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h new file mode 100644 index 0000000..df50237 --- /dev/null +++ b/include/input/InputEventLabels.h @@ -0,0 +1,432 @@ +/* + * 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 _LIBINPUT_INPUT_EVENT_LABELS_H +#define _LIBINPUT_INPUT_EVENT_LABELS_H + +#include <input/Input.h> +#include <android/keycodes.h> + +#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key } +#define DEFINE_AXIS(axis) { #axis, AMOTION_EVENT_AXIS_##axis } +#define DEFINE_LED(led) { #led, ALED_##led } +#define DEFINE_FLAG(flag) { #flag, POLICY_FLAG_##flag } + +namespace android { + +template<typename T, size_t N> +size_t size(T (&)[N]) { return N; } + +struct InputEventLabel { + const char *literal; + int value; +}; + + +static const InputEventLabel KEYCODES[] = { + // NOTE: If you add a new keycode here you must also add it to several other files. + // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. + DEFINE_KEYCODE(UNKNOWN), + DEFINE_KEYCODE(SOFT_LEFT), + DEFINE_KEYCODE(SOFT_RIGHT), + DEFINE_KEYCODE(HOME), + DEFINE_KEYCODE(BACK), + DEFINE_KEYCODE(CALL), + DEFINE_KEYCODE(ENDCALL), + DEFINE_KEYCODE(0), + DEFINE_KEYCODE(1), + DEFINE_KEYCODE(2), + DEFINE_KEYCODE(3), + DEFINE_KEYCODE(4), + DEFINE_KEYCODE(5), + DEFINE_KEYCODE(6), + DEFINE_KEYCODE(7), + DEFINE_KEYCODE(8), + DEFINE_KEYCODE(9), + DEFINE_KEYCODE(STAR), + DEFINE_KEYCODE(POUND), + DEFINE_KEYCODE(DPAD_UP), + DEFINE_KEYCODE(DPAD_DOWN), + DEFINE_KEYCODE(DPAD_LEFT), + DEFINE_KEYCODE(DPAD_RIGHT), + DEFINE_KEYCODE(DPAD_CENTER), + DEFINE_KEYCODE(VOLUME_UP), + DEFINE_KEYCODE(VOLUME_DOWN), + DEFINE_KEYCODE(POWER), + DEFINE_KEYCODE(CAMERA), + DEFINE_KEYCODE(CLEAR), + DEFINE_KEYCODE(A), + DEFINE_KEYCODE(B), + DEFINE_KEYCODE(C), + DEFINE_KEYCODE(D), + DEFINE_KEYCODE(E), + DEFINE_KEYCODE(F), + DEFINE_KEYCODE(G), + DEFINE_KEYCODE(H), + DEFINE_KEYCODE(I), + DEFINE_KEYCODE(J), + DEFINE_KEYCODE(K), + DEFINE_KEYCODE(L), + DEFINE_KEYCODE(M), + DEFINE_KEYCODE(N), + DEFINE_KEYCODE(O), + DEFINE_KEYCODE(P), + DEFINE_KEYCODE(Q), + DEFINE_KEYCODE(R), + DEFINE_KEYCODE(S), + DEFINE_KEYCODE(T), + DEFINE_KEYCODE(U), + DEFINE_KEYCODE(V), + DEFINE_KEYCODE(W), + DEFINE_KEYCODE(X), + DEFINE_KEYCODE(Y), + DEFINE_KEYCODE(Z), + DEFINE_KEYCODE(COMMA), + DEFINE_KEYCODE(PERIOD), + DEFINE_KEYCODE(ALT_LEFT), + DEFINE_KEYCODE(ALT_RIGHT), + DEFINE_KEYCODE(SHIFT_LEFT), + DEFINE_KEYCODE(SHIFT_RIGHT), + DEFINE_KEYCODE(TAB), + DEFINE_KEYCODE(SPACE), + DEFINE_KEYCODE(SYM), + DEFINE_KEYCODE(EXPLORER), + DEFINE_KEYCODE(ENVELOPE), + DEFINE_KEYCODE(ENTER), + DEFINE_KEYCODE(DEL), + DEFINE_KEYCODE(GRAVE), + DEFINE_KEYCODE(MINUS), + DEFINE_KEYCODE(EQUALS), + DEFINE_KEYCODE(LEFT_BRACKET), + DEFINE_KEYCODE(RIGHT_BRACKET), + DEFINE_KEYCODE(BACKSLASH), + DEFINE_KEYCODE(SEMICOLON), + DEFINE_KEYCODE(APOSTROPHE), + DEFINE_KEYCODE(SLASH), + DEFINE_KEYCODE(AT), + DEFINE_KEYCODE(NUM), + DEFINE_KEYCODE(HEADSETHOOK), + DEFINE_KEYCODE(FOCUS), // *Camera* focus + DEFINE_KEYCODE(PLUS), + DEFINE_KEYCODE(MENU), + DEFINE_KEYCODE(NOTIFICATION), + DEFINE_KEYCODE(SEARCH), + DEFINE_KEYCODE(MEDIA_PLAY_PAUSE), + DEFINE_KEYCODE(MEDIA_STOP), + DEFINE_KEYCODE(MEDIA_NEXT), + DEFINE_KEYCODE(MEDIA_PREVIOUS), + DEFINE_KEYCODE(MEDIA_REWIND), + DEFINE_KEYCODE(MEDIA_FAST_FORWARD), + DEFINE_KEYCODE(MUTE), + DEFINE_KEYCODE(PAGE_UP), + DEFINE_KEYCODE(PAGE_DOWN), + DEFINE_KEYCODE(PICTSYMBOLS), + DEFINE_KEYCODE(SWITCH_CHARSET), + DEFINE_KEYCODE(BUTTON_A), + DEFINE_KEYCODE(BUTTON_B), + DEFINE_KEYCODE(BUTTON_C), + DEFINE_KEYCODE(BUTTON_X), + DEFINE_KEYCODE(BUTTON_Y), + DEFINE_KEYCODE(BUTTON_Z), + DEFINE_KEYCODE(BUTTON_L1), + DEFINE_KEYCODE(BUTTON_R1), + DEFINE_KEYCODE(BUTTON_L2), + DEFINE_KEYCODE(BUTTON_R2), + DEFINE_KEYCODE(BUTTON_THUMBL), + DEFINE_KEYCODE(BUTTON_THUMBR), + DEFINE_KEYCODE(BUTTON_START), + DEFINE_KEYCODE(BUTTON_SELECT), + DEFINE_KEYCODE(BUTTON_MODE), + DEFINE_KEYCODE(ESCAPE), + DEFINE_KEYCODE(FORWARD_DEL), + DEFINE_KEYCODE(CTRL_LEFT), + DEFINE_KEYCODE(CTRL_RIGHT), + DEFINE_KEYCODE(CAPS_LOCK), + DEFINE_KEYCODE(SCROLL_LOCK), + DEFINE_KEYCODE(META_LEFT), + DEFINE_KEYCODE(META_RIGHT), + DEFINE_KEYCODE(FUNCTION), + DEFINE_KEYCODE(SYSRQ), + DEFINE_KEYCODE(BREAK), + DEFINE_KEYCODE(MOVE_HOME), + DEFINE_KEYCODE(MOVE_END), + DEFINE_KEYCODE(INSERT), + DEFINE_KEYCODE(FORWARD), + DEFINE_KEYCODE(MEDIA_PLAY), + DEFINE_KEYCODE(MEDIA_PAUSE), + DEFINE_KEYCODE(MEDIA_CLOSE), + DEFINE_KEYCODE(MEDIA_EJECT), + DEFINE_KEYCODE(MEDIA_RECORD), + DEFINE_KEYCODE(F1), + DEFINE_KEYCODE(F2), + DEFINE_KEYCODE(F3), + DEFINE_KEYCODE(F4), + DEFINE_KEYCODE(F5), + DEFINE_KEYCODE(F6), + DEFINE_KEYCODE(F7), + DEFINE_KEYCODE(F8), + DEFINE_KEYCODE(F9), + DEFINE_KEYCODE(F10), + DEFINE_KEYCODE(F11), + DEFINE_KEYCODE(F12), + DEFINE_KEYCODE(NUM_LOCK), + DEFINE_KEYCODE(NUMPAD_0), + DEFINE_KEYCODE(NUMPAD_1), + DEFINE_KEYCODE(NUMPAD_2), + DEFINE_KEYCODE(NUMPAD_3), + DEFINE_KEYCODE(NUMPAD_4), + DEFINE_KEYCODE(NUMPAD_5), + DEFINE_KEYCODE(NUMPAD_6), + DEFINE_KEYCODE(NUMPAD_7), + DEFINE_KEYCODE(NUMPAD_8), + DEFINE_KEYCODE(NUMPAD_9), + DEFINE_KEYCODE(NUMPAD_DIVIDE), + DEFINE_KEYCODE(NUMPAD_MULTIPLY), + DEFINE_KEYCODE(NUMPAD_SUBTRACT), + DEFINE_KEYCODE(NUMPAD_ADD), + DEFINE_KEYCODE(NUMPAD_DOT), + DEFINE_KEYCODE(NUMPAD_COMMA), + DEFINE_KEYCODE(NUMPAD_ENTER), + DEFINE_KEYCODE(NUMPAD_EQUALS), + DEFINE_KEYCODE(NUMPAD_LEFT_PAREN), + DEFINE_KEYCODE(NUMPAD_RIGHT_PAREN), + DEFINE_KEYCODE(VOLUME_MUTE), + DEFINE_KEYCODE(INFO), + DEFINE_KEYCODE(CHANNEL_UP), + DEFINE_KEYCODE(CHANNEL_DOWN), + DEFINE_KEYCODE(ZOOM_IN), + DEFINE_KEYCODE(ZOOM_OUT), + DEFINE_KEYCODE(TV), + DEFINE_KEYCODE(WINDOW), + DEFINE_KEYCODE(GUIDE), + DEFINE_KEYCODE(DVR), + DEFINE_KEYCODE(BOOKMARK), + DEFINE_KEYCODE(CAPTIONS), + DEFINE_KEYCODE(SETTINGS), + DEFINE_KEYCODE(TV_POWER), + DEFINE_KEYCODE(TV_INPUT), + DEFINE_KEYCODE(STB_POWER), + DEFINE_KEYCODE(STB_INPUT), + DEFINE_KEYCODE(AVR_POWER), + DEFINE_KEYCODE(AVR_INPUT), + DEFINE_KEYCODE(PROG_RED), + DEFINE_KEYCODE(PROG_GREEN), + DEFINE_KEYCODE(PROG_YELLOW), + DEFINE_KEYCODE(PROG_BLUE), + DEFINE_KEYCODE(APP_SWITCH), + DEFINE_KEYCODE(BUTTON_1), + DEFINE_KEYCODE(BUTTON_2), + DEFINE_KEYCODE(BUTTON_3), + DEFINE_KEYCODE(BUTTON_4), + DEFINE_KEYCODE(BUTTON_5), + DEFINE_KEYCODE(BUTTON_6), + DEFINE_KEYCODE(BUTTON_7), + DEFINE_KEYCODE(BUTTON_8), + DEFINE_KEYCODE(BUTTON_9), + DEFINE_KEYCODE(BUTTON_10), + DEFINE_KEYCODE(BUTTON_11), + DEFINE_KEYCODE(BUTTON_12), + DEFINE_KEYCODE(BUTTON_13), + DEFINE_KEYCODE(BUTTON_14), + DEFINE_KEYCODE(BUTTON_15), + DEFINE_KEYCODE(BUTTON_16), + DEFINE_KEYCODE(LANGUAGE_SWITCH), + DEFINE_KEYCODE(MANNER_MODE), + DEFINE_KEYCODE(3D_MODE), + DEFINE_KEYCODE(CONTACTS), + DEFINE_KEYCODE(CALENDAR), + DEFINE_KEYCODE(MUSIC), + DEFINE_KEYCODE(CALCULATOR), + DEFINE_KEYCODE(ZENKAKU_HANKAKU), + DEFINE_KEYCODE(EISU), + DEFINE_KEYCODE(MUHENKAN), + DEFINE_KEYCODE(HENKAN), + DEFINE_KEYCODE(KATAKANA_HIRAGANA), + DEFINE_KEYCODE(YEN), + DEFINE_KEYCODE(RO), + DEFINE_KEYCODE(KANA), + DEFINE_KEYCODE(ASSIST), + DEFINE_KEYCODE(BRIGHTNESS_DOWN), + DEFINE_KEYCODE(BRIGHTNESS_UP), + DEFINE_KEYCODE(MEDIA_AUDIO_TRACK), + DEFINE_KEYCODE(SLEEP), + DEFINE_KEYCODE(WAKEUP), + DEFINE_KEYCODE(PAIRING), + DEFINE_KEYCODE(MEDIA_TOP_MENU), + DEFINE_KEYCODE(11), + DEFINE_KEYCODE(12), + DEFINE_KEYCODE(LAST_CHANNEL), + DEFINE_KEYCODE(TV_DATA_SERVICE), + DEFINE_KEYCODE(VOICE_ASSIST), + DEFINE_KEYCODE(TV_RADIO_SERVICE), + DEFINE_KEYCODE(TV_TELETEXT), + DEFINE_KEYCODE(TV_NUMBER_ENTRY), + DEFINE_KEYCODE(TV_TERRESTRIAL_ANALOG), + DEFINE_KEYCODE(TV_TERRESTRIAL_DIGITAL), + DEFINE_KEYCODE(TV_SATELLITE), + DEFINE_KEYCODE(TV_SATELLITE_BS), + DEFINE_KEYCODE(TV_SATELLITE_CS), + DEFINE_KEYCODE(TV_SATELLITE_SERVICE), + DEFINE_KEYCODE(TV_NETWORK), + DEFINE_KEYCODE(TV_ANTENNA_CABLE), + DEFINE_KEYCODE(TV_INPUT_HDMI_1), + DEFINE_KEYCODE(TV_INPUT_HDMI_2), + DEFINE_KEYCODE(TV_INPUT_HDMI_3), + DEFINE_KEYCODE(TV_INPUT_HDMI_4), + DEFINE_KEYCODE(TV_INPUT_COMPOSITE_1), + DEFINE_KEYCODE(TV_INPUT_COMPOSITE_2), + DEFINE_KEYCODE(TV_INPUT_COMPONENT_1), + DEFINE_KEYCODE(TV_INPUT_COMPONENT_2), + DEFINE_KEYCODE(TV_INPUT_VGA_1), + DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION), + DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_UP), + DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_DOWN), + DEFINE_KEYCODE(TV_ZOOM_MODE), + DEFINE_KEYCODE(TV_CONTENTS_MENU), + DEFINE_KEYCODE(TV_MEDIA_CONTEXT_MENU), + DEFINE_KEYCODE(TV_TIMER_PROGRAMMING), + DEFINE_KEYCODE(HELP), + + { NULL, 0 } +}; + +static const InputEventLabel AXES[] = { + DEFINE_AXIS(X), + DEFINE_AXIS(Y), + DEFINE_AXIS(PRESSURE), + DEFINE_AXIS(SIZE), + DEFINE_AXIS(TOUCH_MAJOR), + DEFINE_AXIS(TOUCH_MINOR), + DEFINE_AXIS(TOOL_MAJOR), + DEFINE_AXIS(TOOL_MINOR), + DEFINE_AXIS(ORIENTATION), + DEFINE_AXIS(VSCROLL), + DEFINE_AXIS(HSCROLL), + DEFINE_AXIS(Z), + DEFINE_AXIS(RX), + DEFINE_AXIS(RY), + DEFINE_AXIS(RZ), + DEFINE_AXIS(HAT_X), + DEFINE_AXIS(HAT_Y), + DEFINE_AXIS(LTRIGGER), + DEFINE_AXIS(RTRIGGER), + DEFINE_AXIS(THROTTLE), + DEFINE_AXIS(RUDDER), + DEFINE_AXIS(WHEEL), + DEFINE_AXIS(GAS), + DEFINE_AXIS(BRAKE), + DEFINE_AXIS(DISTANCE), + DEFINE_AXIS(TILT), + DEFINE_AXIS(GENERIC_1), + DEFINE_AXIS(GENERIC_2), + DEFINE_AXIS(GENERIC_3), + DEFINE_AXIS(GENERIC_4), + DEFINE_AXIS(GENERIC_5), + DEFINE_AXIS(GENERIC_6), + DEFINE_AXIS(GENERIC_7), + DEFINE_AXIS(GENERIC_8), + DEFINE_AXIS(GENERIC_9), + DEFINE_AXIS(GENERIC_10), + DEFINE_AXIS(GENERIC_11), + DEFINE_AXIS(GENERIC_12), + DEFINE_AXIS(GENERIC_13), + DEFINE_AXIS(GENERIC_14), + DEFINE_AXIS(GENERIC_15), + DEFINE_AXIS(GENERIC_16), + + // NOTE: If you add a new axis here you must also add it to several other files. + // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. + { NULL, 0 } +}; + +static const InputEventLabel LEDS[] = { + DEFINE_LED(NUM_LOCK), + DEFINE_LED(CAPS_LOCK), + DEFINE_LED(SCROLL_LOCK), + DEFINE_LED(COMPOSE), + DEFINE_LED(KANA), + DEFINE_LED(SLEEP), + DEFINE_LED(SUSPEND), + DEFINE_LED(MUTE), + DEFINE_LED(MISC), + DEFINE_LED(MAIL), + DEFINE_LED(CHARGING), + DEFINE_LED(CONTROLLER_1), + DEFINE_LED(CONTROLLER_2), + DEFINE_LED(CONTROLLER_3), + DEFINE_LED(CONTROLLER_4), + + // NOTE: If you add new LEDs here, you must also add them to Input.h + { NULL, 0 } +}; + +static const InputEventLabel FLAGS[] = { + DEFINE_FLAG(VIRTUAL), + DEFINE_FLAG(FUNCTION), + + { NULL, 0 } +}; + +static int lookupValueByLabel(const char* literal, const InputEventLabel *list) { + while (list->literal) { + if (strcmp(literal, list->literal) == 0) { + return list->value; + } + list++; + } + return list->value; +} + +static const char* lookupLabelByValue(int value, const InputEventLabel* list) { + while (list->literal) { + if (list->value == value) { + return list->literal; + } + list++; + } + return NULL; +} + +static int32_t getKeyCodeByLabel(const char* label) { + return int32_t(lookupValueByLabel(label, KEYCODES)); +} + +static const char* getLabelByKeyCode(int32_t keyCode) { + if (keyCode >= 0 && keyCode < size(KEYCODES)) { + return KEYCODES[keyCode].literal; + } + return NULL; +} + +static uint32_t getKeyFlagByLabel(const char* label) { + return uint32_t(lookupValueByLabel(label, FLAGS)); +} + +static int32_t getAxisByLabel(const char* label) { + return int32_t(lookupValueByLabel(label, AXES)); +} + +static const char* getAxisLabel(int32_t axisId) { + return lookupLabelByValue(axisId, AXES); +} + +static int32_t getLedByLabel(const char* label) { + return int32_t(lookupValueByLabel(label, LEDS)); +} + + +} // namespace android +#endif // _LIBINPUT_INPUT_EVENT_LABELS_H diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 609b679..e7e383b 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -39,6 +39,9 @@ namespace android { /* * Intermediate representation used to send input events and related signals. + * + * Note that this structure is used for IPCs so its layout must be identical + * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp. */ struct InputMessage { enum { @@ -49,13 +52,17 @@ struct InputMessage { struct Header { uint32_t type; - uint32_t padding; // 8 byte alignment for the body that follows + // We don't need this field in order to align the body below but we + // leave it here because InputMessage::size() and other functions + // compute the size of this structure as sizeof(Header) + sizeof(Body). + uint32_t padding; } header; + // Body *must* be 8 byte aligned. union Body { struct Key { uint32_t seq; - nsecs_t eventTime; + nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; int32_t action; @@ -64,7 +71,7 @@ struct InputMessage { int32_t scanCode; int32_t metaState; int32_t repeatCount; - nsecs_t downTime; + nsecs_t downTime __attribute__((aligned(8))); inline size_t size() const { return sizeof(Key); @@ -73,7 +80,7 @@ struct InputMessage { struct Motion { uint32_t seq; - nsecs_t eventTime; + nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; int32_t action; @@ -81,13 +88,14 @@ struct InputMessage { int32_t metaState; int32_t buttonState; int32_t edgeFlags; - nsecs_t downTime; + nsecs_t downTime __attribute__((aligned(8))); float xOffset; float yOffset; float xPrecision; float yPrecision; - size_t pointerCount; - struct Pointer { + uint32_t pointerCount; + // Note that PointerCoords requires 8 byte alignment. + struct Pointer{ PointerProperties properties; PointerCoords coords; } pointers[MAX_POINTERS]; @@ -112,7 +120,7 @@ struct InputMessage { return sizeof(Finished); } } finished; - } body; + } __attribute__((aligned(8))) body; bool isValid(size_t actualSize) const; size_t size() const; @@ -234,7 +242,7 @@ public: float yPrecision, nsecs_t downTime, nsecs_t eventTime, - size_t pointerCount, + uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); @@ -360,7 +368,7 @@ private: void initializeFrom(const InputMessage* msg) { eventTime = msg->body.motion.eventTime; idBits.clear(); - for (size_t i = 0; i < msg->body.motion.pointerCount; i++) { + for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) { uint32_t id = msg->body.motion.pointers[i].properties.id; idBits.markBit(id); idToIndex[id] = i; diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h index 25b2f07..519bb22 100644 --- a/include/input/Keyboard.h +++ b/include/input/Keyboard.h @@ -19,6 +19,7 @@ #include <input/Input.h> #include <input/InputDevice.h> +#include <input/InputEventLabels.h> #include <utils/Errors.h> #include <utils/String8.h> #include <utils/PropertyMap.h> @@ -82,36 +83,6 @@ extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentif const PropertyMap* deviceConfiguration, const KeyMap* keyMap); /** - * Gets a key code by its short form label, eg. "HOME". - * Returns 0 if unknown. - */ -extern int32_t getKeyCodeByLabel(const char* label); - -/** - * Gets a key flag by its short form label, eg. "WAKE". - * Returns 0 if unknown. - */ -extern uint32_t getKeyFlagByLabel(const char* label); - -/** - * Gets an axis by its short form label, eg. "X". - * Returns -1 if unknown. - */ -extern int32_t getAxisByLabel(const char* label); - -/** - * Gets an axis label by its id. - * Returns NULL if unknown. - */ -extern const char* getAxisLabel(int32_t axisId); - -/** - * Gets an LED by its short form label, eg. "CAPS_LOCK". - * Returns -1 if unknown. - */ -extern int32_t getLedByLabel(const char* label); - -/** * Updates a meta state field when a key is pressed or released. */ extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState); diff --git a/include/input/KeycodeLabels.h b/include/input/KeycodeLabels.h deleted file mode 100644 index a8d63da..0000000 --- a/include/input/KeycodeLabels.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * 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 _LIBINPUT_KEYCODE_LABELS_H -#define _LIBINPUT_KEYCODE_LABELS_H - -#include <android/keycodes.h> - -struct KeycodeLabel { - const char *literal; - int value; -}; - -static const KeycodeLabel KEYCODES[] = { - { "SOFT_LEFT", 1 }, - { "SOFT_RIGHT", 2 }, - { "HOME", 3 }, - { "BACK", 4 }, - { "CALL", 5 }, - { "ENDCALL", 6 }, - { "0", 7 }, - { "1", 8 }, - { "2", 9 }, - { "3", 10 }, - { "4", 11 }, - { "5", 12 }, - { "6", 13 }, - { "7", 14 }, - { "8", 15 }, - { "9", 16 }, - { "STAR", 17 }, - { "POUND", 18 }, - { "DPAD_UP", 19 }, - { "DPAD_DOWN", 20 }, - { "DPAD_LEFT", 21 }, - { "DPAD_RIGHT", 22 }, - { "DPAD_CENTER", 23 }, - { "VOLUME_UP", 24 }, - { "VOLUME_DOWN", 25 }, - { "POWER", 26 }, - { "CAMERA", 27 }, - { "CLEAR", 28 }, - { "A", 29 }, - { "B", 30 }, - { "C", 31 }, - { "D", 32 }, - { "E", 33 }, - { "F", 34 }, - { "G", 35 }, - { "H", 36 }, - { "I", 37 }, - { "J", 38 }, - { "K", 39 }, - { "L", 40 }, - { "M", 41 }, - { "N", 42 }, - { "O", 43 }, - { "P", 44 }, - { "Q", 45 }, - { "R", 46 }, - { "S", 47 }, - { "T", 48 }, - { "U", 49 }, - { "V", 50 }, - { "W", 51 }, - { "X", 52 }, - { "Y", 53 }, - { "Z", 54 }, - { "COMMA", 55 }, - { "PERIOD", 56 }, - { "ALT_LEFT", 57 }, - { "ALT_RIGHT", 58 }, - { "SHIFT_LEFT", 59 }, - { "SHIFT_RIGHT", 60 }, - { "TAB", 61 }, - { "SPACE", 62 }, - { "SYM", 63 }, - { "EXPLORER", 64 }, - { "ENVELOPE", 65 }, - { "ENTER", 66 }, - { "DEL", 67 }, - { "GRAVE", 68 }, - { "MINUS", 69 }, - { "EQUALS", 70 }, - { "LEFT_BRACKET", 71 }, - { "RIGHT_BRACKET", 72 }, - { "BACKSLASH", 73 }, - { "SEMICOLON", 74 }, - { "APOSTROPHE", 75 }, - { "SLASH", 76 }, - { "AT", 77 }, - { "NUM", 78 }, - { "HEADSETHOOK", 79 }, - { "FOCUS", 80 }, - { "PLUS", 81 }, - { "MENU", 82 }, - { "NOTIFICATION", 83 }, - { "SEARCH", 84 }, - { "MEDIA_PLAY_PAUSE", 85 }, - { "MEDIA_STOP", 86 }, - { "MEDIA_NEXT", 87 }, - { "MEDIA_PREVIOUS", 88 }, - { "MEDIA_REWIND", 89 }, - { "MEDIA_FAST_FORWARD", 90 }, - { "MUTE", 91 }, - { "PAGE_UP", 92 }, - { "PAGE_DOWN", 93 }, - { "PICTSYMBOLS", 94 }, - { "SWITCH_CHARSET", 95 }, - { "BUTTON_A", 96 }, - { "BUTTON_B", 97 }, - { "BUTTON_C", 98 }, - { "BUTTON_X", 99 }, - { "BUTTON_Y", 100 }, - { "BUTTON_Z", 101 }, - { "BUTTON_L1", 102 }, - { "BUTTON_R1", 103 }, - { "BUTTON_L2", 104 }, - { "BUTTON_R2", 105 }, - { "BUTTON_THUMBL", 106 }, - { "BUTTON_THUMBR", 107 }, - { "BUTTON_START", 108 }, - { "BUTTON_SELECT", 109 }, - { "BUTTON_MODE", 110 }, - { "ESCAPE", 111 }, - { "FORWARD_DEL", 112 }, - { "CTRL_LEFT", 113 }, - { "CTRL_RIGHT", 114 }, - { "CAPS_LOCK", 115 }, - { "SCROLL_LOCK", 116 }, - { "META_LEFT", 117 }, - { "META_RIGHT", 118 }, - { "FUNCTION", 119 }, - { "SYSRQ", 120 }, - { "BREAK", 121 }, - { "MOVE_HOME", 122 }, - { "MOVE_END", 123 }, - { "INSERT", 124 }, - { "FORWARD", 125 }, - { "MEDIA_PLAY", 126 }, - { "MEDIA_PAUSE", 127 }, - { "MEDIA_CLOSE", 128 }, - { "MEDIA_EJECT", 129 }, - { "MEDIA_RECORD", 130 }, - { "F1", 131 }, - { "F2", 132 }, - { "F3", 133 }, - { "F4", 134 }, - { "F5", 135 }, - { "F6", 136 }, - { "F7", 137 }, - { "F8", 138 }, - { "F9", 139 }, - { "F10", 140 }, - { "F11", 141 }, - { "F12", 142 }, - { "NUM_LOCK", 143 }, - { "NUMPAD_0", 144 }, - { "NUMPAD_1", 145 }, - { "NUMPAD_2", 146 }, - { "NUMPAD_3", 147 }, - { "NUMPAD_4", 148 }, - { "NUMPAD_5", 149 }, - { "NUMPAD_6", 150 }, - { "NUMPAD_7", 151 }, - { "NUMPAD_8", 152 }, - { "NUMPAD_9", 153 }, - { "NUMPAD_DIVIDE", 154 }, - { "NUMPAD_MULTIPLY", 155 }, - { "NUMPAD_SUBTRACT", 156 }, - { "NUMPAD_ADD", 157 }, - { "NUMPAD_DOT", 158 }, - { "NUMPAD_COMMA", 159 }, - { "NUMPAD_ENTER", 160 }, - { "NUMPAD_EQUALS", 161 }, - { "NUMPAD_LEFT_PAREN", 162 }, - { "NUMPAD_RIGHT_PAREN", 163 }, - { "VOLUME_MUTE", 164 }, - { "INFO", 165 }, - { "CHANNEL_UP", 166 }, - { "CHANNEL_DOWN", 167 }, - { "ZOOM_IN", 168 }, - { "ZOOM_OUT", 169 }, - { "TV", 170 }, - { "WINDOW", 171 }, - { "GUIDE", 172 }, - { "DVR", 173 }, - { "BOOKMARK", 174 }, - { "CAPTIONS", 175 }, - { "SETTINGS", 176 }, - { "TV_POWER", 177 }, - { "TV_INPUT", 178 }, - { "STB_POWER", 179 }, - { "STB_INPUT", 180 }, - { "AVR_POWER", 181 }, - { "AVR_INPUT", 182 }, - { "PROG_RED", 183 }, - { "PROG_GREEN", 184 }, - { "PROG_YELLOW", 185 }, - { "PROG_BLUE", 186 }, - { "APP_SWITCH", 187 }, - { "BUTTON_1", 188 }, - { "BUTTON_2", 189 }, - { "BUTTON_3", 190 }, - { "BUTTON_4", 191 }, - { "BUTTON_5", 192 }, - { "BUTTON_6", 193 }, - { "BUTTON_7", 194 }, - { "BUTTON_8", 195 }, - { "BUTTON_9", 196 }, - { "BUTTON_10", 197 }, - { "BUTTON_11", 198 }, - { "BUTTON_12", 199 }, - { "BUTTON_13", 200 }, - { "BUTTON_14", 201 }, - { "BUTTON_15", 202 }, - { "BUTTON_16", 203 }, - { "LANGUAGE_SWITCH", 204 }, - { "MANNER_MODE", 205 }, - { "3D_MODE", 206 }, - { "CONTACTS", 207 }, - { "CALENDAR", 208 }, - { "MUSIC", 209 }, - { "CALCULATOR", 210 }, - { "ZENKAKU_HANKAKU", 211 }, - { "EISU", 212 }, - { "MUHENKAN", 213 }, - { "HENKAN", 214 }, - { "KATAKANA_HIRAGANA", 215 }, - { "YEN", 216 }, - { "RO", 217 }, - { "KANA", 218 }, - { "ASSIST", 219 }, - { "BRIGHTNESS_DOWN", 220 }, - { "BRIGHTNESS_UP", 221 }, - { "MEDIA_AUDIO_TRACK", 222 }, - { "SLEEP", 223 }, - { "WAKEUP", 224 }, - - // NOTE: If you add a new keycode here you must also add it to several other files. - // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. - - { NULL, 0 } -}; - -// NOTE: If you edit these flags, also edit policy flags in Input.h. -static const KeycodeLabel FLAGS[] = { - { "WAKE", 0x00000001 }, - { "WAKE_DROPPED", 0x00000002 }, - { "SHIFT", 0x00000004 }, - { "CAPS_LOCK", 0x00000008 }, - { "ALT", 0x00000010 }, - { "ALT_GR", 0x00000020 }, - { "MENU", 0x00000040 }, - { "LAUNCHER", 0x00000080 }, - { "VIRTUAL", 0x00000100 }, - { "FUNCTION", 0x00000200 }, - { NULL, 0 } -}; - -static const KeycodeLabel AXES[] = { - { "X", 0 }, - { "Y", 1 }, - { "PRESSURE", 2 }, - { "SIZE", 3 }, - { "TOUCH_MAJOR", 4 }, - { "TOUCH_MINOR", 5 }, - { "TOOL_MAJOR", 6 }, - { "TOOL_MINOR", 7 }, - { "ORIENTATION", 8 }, - { "VSCROLL", 9 }, - { "HSCROLL", 10 }, - { "Z", 11 }, - { "RX", 12 }, - { "RY", 13 }, - { "RZ", 14 }, - { "HAT_X", 15 }, - { "HAT_Y", 16 }, - { "LTRIGGER", 17 }, - { "RTRIGGER", 18 }, - { "THROTTLE", 19 }, - { "RUDDER", 20 }, - { "WHEEL", 21 }, - { "GAS", 22 }, - { "BRAKE", 23 }, - { "DISTANCE", 24 }, - { "TILT", 25 }, - { "GENERIC_1", 32 }, - { "GENERIC_2", 33 }, - { "GENERIC_3", 34 }, - { "GENERIC_4", 35 }, - { "GENERIC_5", 36 }, - { "GENERIC_6", 37 }, - { "GENERIC_7", 38 }, - { "GENERIC_8", 39 }, - { "GENERIC_9", 40 }, - { "GENERIC_10", 41 }, - { "GENERIC_11", 42 }, - { "GENERIC_12", 43 }, - { "GENERIC_13", 44 }, - { "GENERIC_14", 45 }, - { "GENERIC_15", 46 }, - { "GENERIC_16", 47 }, - - // NOTE: If you add a new axis here you must also add it to several other files. - // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. - - { NULL, -1 } -}; - -static const KeycodeLabel LEDS[] = { - { "NUM_LOCK", 0x00 }, - { "CAPS_LOCK", 0x01 }, - { "SCROLL_LOCK", 0x02 }, - { "COMPOSE", 0x03 }, - { "KANA", 0x04 }, - { "SLEEP", 0x05 }, - { "SUSPEND", 0x06 }, - { "MUTE", 0x07 }, - { "MISC", 0x08 }, - { "MAIL", 0x09 }, - { "CHARGING", 0x0a }, - { "CONTROLLER_1", 0x10 }, - { "CONTROLLER_2", 0x11 }, - { "CONTROLLER_3", 0x12 }, - { "CONTROLLER_4", 0x13 }, - - // NOTE: If you add new LEDs here, you must also add them to Input.h - - { NULL, -1 } -}; - -#endif // _LIBINPUT_KEYCODE_LABELS_H diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h index fc6b49c..4633b7e 100644 --- a/include/media/drm/DrmAPI.h +++ b/include/media/drm/DrmAPI.h @@ -189,6 +189,9 @@ namespace android { Vector<uint8_t> &certificate, Vector<uint8_t> &wrapped_key) = 0; + // Remove device provisioning. + virtual status_t unprovisionDevice() = 0; + // A means of enforcing the contractual requirement for a concurrent stream // limit per subscriber across devices is provided via SecureStop. SecureStop // is a means of securely monitoring the lifetime of sessions. Since playback diff --git a/include/media/hardware/CryptoAPI.h b/include/media/hardware/CryptoAPI.h index 44a0040..c800825 100644 --- a/include/media/hardware/CryptoAPI.h +++ b/include/media/hardware/CryptoAPI.h @@ -51,8 +51,8 @@ struct CryptoPlugin { }; struct SubSample { - size_t mNumBytesOfClearData; - size_t mNumBytesOfEncryptedData; + uint32_t mNumBytesOfClearData; + uint32_t mNumBytesOfEncryptedData; }; CryptoPlugin() {} @@ -64,6 +64,12 @@ struct CryptoPlugin { // media data of the given mime type. virtual bool requiresSecureDecoderComponent(const char *mime) const = 0; + // To implement resolution constraints, the crypto plugin needs to know + // the resolution of the video being decrypted. The media player should + // call this method when the resolution is determined and any time it + // is subsequently changed. + virtual void notifyResolution(uint32_t width, uint32_t height) {} + // If the error returned falls into the range // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be // filled in with an appropriate string. diff --git a/include/media/hardware/HDCPAPI.h b/include/media/hardware/HDCPAPI.h index d4abb3f..3a53e9f 100644 --- a/include/media/hardware/HDCPAPI.h +++ b/include/media/hardware/HDCPAPI.h @@ -88,6 +88,11 @@ struct HDCPModule { // Request to shutdown the active HDCP session. virtual status_t shutdownAsync() = 0; + // Returns the capability bitmask of this HDCP session. + virtual uint32_t getCaps() { + return HDCP_CAPS_ENCRYPT; + } + // ENCRYPTION only: // Encrypt data according to the HDCP spec. "size" bytes of data are // available at "inData" (virtual address), "size" may not be a multiple diff --git a/include/media/hardware/HardwareAPI.h b/include/media/hardware/HardwareAPI.h index de3aeb1..90150c6 100644 --- a/include/media/hardware/HardwareAPI.h +++ b/include/media/hardware/HardwareAPI.h @@ -157,6 +157,84 @@ struct PrependSPSPPSToIDRFramesParams { OMX_BOOL bEnable; }; +// Structure describing a media image (frame) +// Currently only supporting YUV +struct MediaImage { + enum Type { + MEDIA_IMAGE_TYPE_UNKNOWN = 0, + MEDIA_IMAGE_TYPE_YUV, + }; + + enum PlaneIndex { + Y = 0, + U, + V, + MAX_NUM_PLANES + }; + + Type mType; + size_t mNumPlanes; // number of planes + size_t mWidth; // width of largest plane + size_t mHeight; // height of largest plane + size_t mBitDepth; // useable bit depth + struct PlaneInfo { + size_t mOffset; // offset of first pixel of the plane in bytes + // from buffer offset + size_t mColInc; // column increment in bytes + size_t mRowInc; // row increment in bytes + size_t mHorizSubsampling; // subsampling compared to the largest plane + size_t mVertSubsampling; // subsampling compared to the largest plane + }; + PlaneInfo mPlane[MAX_NUM_PLANES]; +}; + +// A pointer to this struct is passed to OMX_GetParameter when the extension +// index for the 'OMX.google.android.index.describeColorFormat' +// extension is given. This method can be called from any component state +// other than invalid. The color-format, frame width/height, and stride/ +// slice-height parameters are ones that are associated with a raw video +// port (input or output), but the stride/slice height parameters may be +// incorrect. The component shall fill out the MediaImage structure that +// corresponds to the described raw video format, and the potentially corrected +// stride and slice-height info. +// +// For non-YUV packed planar/semiplanar image formats, the component shall set +// mNumPlanes to 0, and mType to MEDIA_IMAGE_TYPE_UNKNOWN. +struct DescribeColorFormatParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + // input: parameters from OMX_VIDEO_PORTDEFINITIONTYPE + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_U32 nStride; + OMX_U32 nSliceHeight; + + // output: fill out the MediaImage fields + MediaImage sMediaImage; +}; + +// A pointer to this struct is passed to OMX_SetParameter or OMX_GetParameter +// when the extension index for the +// 'OMX.google.android.index.configureVideoTunnelMode' extension is given. +// If the extension is supported then tunneled playback mode should be supported +// by the codec. If bTunneled is set to OMX_TRUE then the video decoder should +// operate in "tunneled" mode and output its decoded frames directly to the +// sink. In this case nAudioHwSync is the HW SYNC ID of the audio HAL Output +// stream to sync the video with. If bTunneled is set to OMX_FALSE, "tunneled" +// mode should be disabled and nAudioHwSync should be ignored. +// OMX_GetParameter is used to query tunneling configuration. bTunneled should +// return whether decoder is operating in tunneled mode, and if it is, +// pSidebandWindow should contain the codec allocated sideband window handle. +struct ConfigureVideoTunnelModeParams { + OMX_U32 nSize; // IN + OMX_VERSIONTYPE nVersion; // IN + OMX_U32 nPortIndex; // IN + OMX_BOOL bTunneled; // IN/OUT + OMX_U32 nAudioHwSync; // IN + OMX_PTR pSidebandWindow; // OUT +}; + } // namespace android extern android::OMXPluginBase *createOMXPlugin(); diff --git a/include/media/hardware/MetadataBufferType.h b/include/media/hardware/MetadataBufferType.h index 4eaf8ac..5876c40 100644 --- a/include/media/hardware/MetadataBufferType.h +++ b/include/media/hardware/MetadataBufferType.h @@ -82,6 +82,24 @@ typedef enum { */ kMetadataBufferTypeGrallocSource = 1, + /* + * kMetadataBufferTypeGraphicBuffer is used to indicate that + * the payload of the metadata buffers can be interpreted as + * a GraphicBuffer. It is only to be used by software encoders. + * In this case, the metadata that the encoder receives + * will have a byte stream that consists of two parts: + * 1. First, there is an integer indicating that the metadata + * contains a GraphicBuffer (kMetadataBufferTypeGraphicBuffer) + * 2. This is followed by the pointer to the GraphicBuffer that + * is to be encoded. Encoder must not create a sp<> from this + * graphic buffer, or free it, as it does not actually own this + * buffer. + * -------------------------------------------------------------- + * | kMetadataBufferTypeGraphicBuffer | sizeof(GraphicBuffer *) | + * -------------------------------------------------------------- + */ + kMetadataBufferTypeGraphicBuffer = 2, + // Add more here... } MetadataBufferType; diff --git a/include/media/openmax/OMX_Audio.h b/include/media/openmax/OMX_Audio.h index 89ce0fc..f4cb643 100644 --- a/include/media/openmax/OMX_Audio.h +++ b/include/media/openmax/OMX_Audio.h @@ -278,6 +278,7 @@ typedef enum OMX_AUDIO_AACPROFILETYPE{ #define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ #define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ #define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ +#define OMX_AUDIO_AACToolVendor 0x00010000 /**< NOT A KHRONOS VALUE, offset for vendor-specific additions */ #define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ /** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). diff --git a/include/media/openmax/OMX_AudioExt.h b/include/media/openmax/OMX_AudioExt.h index aa6e6d0..5ac15f7 100644 --- a/include/media/openmax/OMX_AudioExt.h +++ b/include/media/openmax/OMX_AudioExt.h @@ -40,9 +40,13 @@ extern "C" { */ #include <OMX_Core.h> +#define OMX_AUDIO_AACToolAndroidSSBR (OMX_AUDIO_AACToolVendor << 0) /**< SSBR: MPEG-4 Single-rate (downsampled) Spectral Band Replication tool allowed or active */ +#define OMX_AUDIO_AACToolAndroidDSBR (OMX_AUDIO_AACToolVendor << 1) /**< DSBR: MPEG-4 Dual-rate Spectral Band Replication tool allowed or active */ + typedef enum OMX_AUDIO_CODINGEXTTYPE { OMX_AUDIO_CodingAndroidUnused = OMX_AUDIO_CodingKhronosExtensions + 0x00100000, OMX_AUDIO_CodingAndroidAC3, /**< AC3 encoded data */ + OMX_AUDIO_CodingAndroidOPUS, /**< OPUS encoded data */ } OMX_AUDIO_CODINGEXTTYPE; typedef struct OMX_AUDIO_PARAM_ANDROID_AC3TYPE { @@ -54,6 +58,32 @@ typedef struct OMX_AUDIO_PARAM_ANDROID_AC3TYPE { variable or unknown sampling rate. */ } OMX_AUDIO_PARAM_ANDROID_AC3TYPE; +typedef struct OMX_AUDIO_PARAM_ANDROID_OPUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable + rate or unknown bit rates. Encoding is set to the + bitrate closest to specified value (in bps) */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ +} OMX_AUDIO_PARAM_ANDROID_OPUSTYPE; + +typedef struct OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 nMaxOutputChannels; /**< Maximum channel count to be output, -1 if unspecified, 0 if downmixing disabled */ + OMX_S32 nDrcCut; /**< The DRC attenuation factor, between 0 and 127, -1 if unspecified */ + OMX_S32 nDrcBoost; /**< The DRC amplification factor, between 0 and 127, -1 if unspecified */ + OMX_S32 nHeavyCompression; /**< 0 for light compression, 1 for heavy compression, -1 if unspecified */ + OMX_S32 nTargetReferenceLevel; /**< Target reference level, between 0 and 127, -1 if unspecified */ + OMX_S32 nEncodedTargetLevel; /**< Target reference level assumed at the encoder, between 0 and 127, -1 if unspecified */ + OMX_S32 nPCMLimiterEnable; /**< Signal level limiting, 0 for disable, 1 for enable, -1 if unspecified */ +} OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE; + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/media/openmax/OMX_IVCommon.h b/include/media/openmax/OMX_IVCommon.h index 96a4396..5f9e9b6 100644 --- a/include/media/openmax/OMX_IVCommon.h +++ b/include/media/openmax/OMX_IVCommon.h @@ -157,6 +157,13 @@ typedef enum OMX_COLOR_FORMATTYPE { * an acceptable range once that is done. * */ OMX_COLOR_FormatAndroidOpaque = 0x7F000789, + /** Flexible 8-bit YUV format. Codec should report this format + * as being supported if it supports any YUV420 packed planar + * or semiplanar formats. When port is set to use this format, + * codec can substitute any YUV420 packed planar or semiplanar + * format for it. */ + OMX_COLOR_FormatYUV420Flexible = 0x7F420888, + OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100, OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00, OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03, diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h index c47a885..6cd774b 100644 --- a/include/media/openmax/OMX_IndexExt.h +++ b/include/media/openmax/OMX_IndexExt.h @@ -58,6 +58,8 @@ typedef enum OMX_INDEXEXTTYPE { /* Audio parameters and configurations */ OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000, OMX_IndexParamAudioAndroidAc3, /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */ + OMX_IndexParamAudioAndroidOpus, /**< reference: OMX_AUDIO_PARAM_ANDROID_OPUSTYPE */ + OMX_IndexParamAudioAndroidAacPresentation, /**< reference: OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE */ /* Image parameters and configurations */ OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000, @@ -70,6 +72,9 @@ typedef enum OMX_INDEXEXTTYPE { OMX_IndexParamVideoVp8, /**< reference: OMX_VIDEO_PARAM_VP8TYPE */ OMX_IndexConfigVideoVp8ReferenceFrame, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */ OMX_IndexConfigVideoVp8ReferenceFrameType, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */ + OMX_IndexParamVideoAndroidVp8Encoder, /**< reference: OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE */ + OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */ + OMX_IndexParamSliceSegments, /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */ /* Image & Video common configurations */ OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000, diff --git a/include/media/openmax/OMX_Types.h b/include/media/openmax/OMX_Types.h index 03fd4bc..71e346a 100644 --- a/include/media/openmax/OMX_Types.h +++ b/include/media/openmax/OMX_Types.h @@ -48,6 +48,8 @@ #ifndef OMX_Types_h #define OMX_Types_h +#include <stdint.h> + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -160,10 +162,10 @@ typedef unsigned short OMX_U16; typedef signed short OMX_S16; /** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ -typedef unsigned long OMX_U32; +typedef uint32_t OMX_U32; /** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ -typedef signed long OMX_S32; +typedef int32_t OMX_S32; /* Users with compilers that cannot accept the "long long" designation should @@ -209,7 +211,25 @@ typedef enum OMX_BOOL { OMX_TRUE = !OMX_FALSE, OMX_BOOL_MAX = 0x7FFFFFFF } OMX_BOOL; - + +/* + * Temporary Android 64 bit modification + * + * #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + * overrides all OMX pointer types to be uint32_t. + * + * After this change, OMX codecs will work in 32 bit only, so 64 bit processes + * must communicate to a remote 32 bit process for OMX to work. + */ + +#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + +typedef uint32_t OMX_PTR; +typedef OMX_PTR OMX_STRING; +typedef OMX_PTR OMX_BYTE; + +#else /* OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS */ + /** The OMX_PTR type is intended to be used to pass pointers between the OMX applications and the OMX Core and components. This is a 32 bit pointer and is aligned on a 32 bit boundary. @@ -230,6 +250,8 @@ typedef char* OMX_STRING; */ typedef unsigned char* OMX_BYTE; +#endif /* OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS */ + /** OMX_UUIDTYPE is a very long unique identifier to uniquely identify at runtime. This identifier should be generated by a component in a way that guarantees that every instance of the identifier running on the system @@ -310,7 +332,7 @@ typedef struct OMX_TICKS /** Define the public interface for the OMX Handle. The core will not use this value internally, but the application should only use this value. */ -typedef void* OMX_HANDLETYPE; +typedef OMX_PTR OMX_HANDLETYPE; typedef struct OMX_MARKTYPE { @@ -326,11 +348,11 @@ typedef struct OMX_MARKTYPE /** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the * platform & operating specific object used to reference the display * or can be used by a audio port for native audio rendering */ -typedef void* OMX_NATIVE_DEVICETYPE; +typedef OMX_PTR OMX_NATIVE_DEVICETYPE; /** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the * platform & operating specific object used to reference the window */ -typedef void* OMX_NATIVE_WINDOWTYPE; +typedef OMX_PTR OMX_NATIVE_WINDOWTYPE; /** The OMX_VERSIONTYPE union is used to specify the version for a structure or component. For a component, the version is entirely diff --git a/include/media/openmax/OMX_Video.h b/include/media/openmax/OMX_Video.h index 4441a7a..89425e0 100644 --- a/include/media/openmax/OMX_Video.h +++ b/include/media/openmax/OMX_Video.h @@ -87,6 +87,7 @@ typedef enum OMX_VIDEO_CODINGTYPE { OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ OMX_VIDEO_CodingVP8, /**< Google VP8, formerly known as On2 VP8 */ OMX_VIDEO_CodingVP9, /**< Google VP9 */ + OMX_VIDEO_CodingHEVC, /**< ITU H.265/HEVC */ OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ OMX_VIDEO_CodingMax = 0x7FFFFFFF @@ -817,6 +818,7 @@ typedef enum OMX_VIDEO_AVCLEVELTYPE { OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ + OMX_VIDEO_AVCLevel52 = 0x10000, /**< Level 5.2 */ OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h index fa24168..3c97e14 100644 --- a/include/media/openmax/OMX_VideoExt.h +++ b/include/media/openmax/OMX_VideoExt.h @@ -108,6 +108,100 @@ typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE { OMX_BOOL bIsGoldenOrAlternateFrame; } OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE; +/** Maximum number of VP8 temporal layers */ +#define OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS 3 + +/** VP8 temporal layer patterns */ +typedef enum OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE { + OMX_VIDEO_VPXTemporalLayerPatternNone = 0, + OMX_VIDEO_VPXTemporalLayerPatternWebRTC = 1, + OMX_VIDEO_VPXTemporalLayerPatternMax = 0x7FFFFFFF +} OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE; + +/** + * Android specific VP8 encoder params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nKeyFrameInterval : Key frame interval in frames + * eTemporalPattern : Type of temporal layer pattern + * nTemporalLayerCount : Number of temporal coding layers + * nTemporalLayerBitrateRatio : Bitrate ratio allocation between temporal + * streams in percentage + * nMinQuantizer : Minimum (best quality) quantizer + * nMaxQuantizer : Maximum (worst quality) quantizer + */ +typedef struct OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nKeyFrameInterval; + OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE eTemporalPattern; + OMX_U32 nTemporalLayerCount; + OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]; + OMX_U32 nMinQuantizer; + OMX_U32 nMaxQuantizer; +} OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE; + +/** HEVC Profile enum type */ +typedef enum OMX_VIDEO_HEVCPROFILETYPE { + OMX_VIDEO_HEVCProfileUnknown = 0x0, + OMX_VIDEO_HEVCProfileMain = 0x1, + OMX_VIDEO_HEVCProfileMain10 = 0x2, + OMX_VIDEO_HEVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_HEVCPROFILETYPE; + +/** HEVC Level enum type */ +typedef enum OMX_VIDEO_HEVCLEVELTYPE { + OMX_VIDEO_HEVCLevelUnknown = 0x0, + OMX_VIDEO_HEVCMainTierLevel1 = 0x1, + OMX_VIDEO_HEVCHighTierLevel1 = 0x2, + OMX_VIDEO_HEVCMainTierLevel2 = 0x4, + OMX_VIDEO_HEVCHighTierLevel2 = 0x8, + OMX_VIDEO_HEVCMainTierLevel21 = 0x10, + OMX_VIDEO_HEVCHighTierLevel21 = 0x20, + OMX_VIDEO_HEVCMainTierLevel3 = 0x40, + OMX_VIDEO_HEVCHighTierLevel3 = 0x80, + OMX_VIDEO_HEVCMainTierLevel31 = 0x100, + OMX_VIDEO_HEVCHighTierLevel31 = 0x200, + OMX_VIDEO_HEVCMainTierLevel4 = 0x400, + OMX_VIDEO_HEVCHighTierLevel4 = 0x800, + OMX_VIDEO_HEVCMainTierLevel41 = 0x1000, + OMX_VIDEO_HEVCHighTierLevel41 = 0x2000, + OMX_VIDEO_HEVCMainTierLevel5 = 0x4000, + OMX_VIDEO_HEVCHighTierLevel5 = 0x8000, + OMX_VIDEO_HEVCMainTierLevel51 = 0x10000, + OMX_VIDEO_HEVCHighTierLevel51 = 0x20000, + OMX_VIDEO_HEVCMainTierLevel52 = 0x40000, + OMX_VIDEO_HEVCHighTierLevel52 = 0x80000, + OMX_VIDEO_HEVCMainTierLevel6 = 0x100000, + OMX_VIDEO_HEVCHighTierLevel6 = 0x200000, + OMX_VIDEO_HEVCMainTierLevel61 = 0x400000, + OMX_VIDEO_HEVCHighTierLevel61 = 0x800000, + OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000, + OMX_VIDEO_HEVCHighTierLevel62 = 0x2000000, + OMX_VIDEO_HEVCHighTiermax = 0x7FFFFFFF +} OMX_VIDEO_HEVCLEVELTYPE; + +/** Structure for controlling HEVC video encoding and decoding */ +typedef struct OMX_VIDEO_PARAM_HEVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_HEVCPROFILETYPE eProfile; + OMX_VIDEO_HEVCLEVELTYPE eLevel; +} OMX_VIDEO_PARAM_HEVCTYPE; + +/** Structure to define if dependent slice segments should be used */ +typedef struct OMX_VIDEO_SLICESEGMENTSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bDepedentSegments; + OMX_BOOL bEnableLoopFilterAcrossSlices; +} OMX_VIDEO_SLICESEGMENTSTYPE; #ifdef __cplusplus } diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h index d85003f..91ecc5a 100644 --- a/include/powermanager/IPowerManager.h +++ b/include/powermanager/IPowerManager.h @@ -19,6 +19,7 @@ #include <utils/Errors.h> #include <binder/IInterface.h> +#include <hardware/power.h> namespace android { @@ -30,12 +31,16 @@ class IPowerManager : public IInterface public: DECLARE_META_INTERFACE(PowerManager); + // FIXME remove the bool isOneWay parameters as they are not oneway in the .aidl virtual status_t acquireWakeLock(int flags, const sp<IBinder>& lock, const String16& tag, - const String16& packageName) = 0; + const String16& packageName, bool isOneWay = false) = 0; virtual status_t acquireWakeLockWithUid(int flags, const sp<IBinder>& lock, const String16& tag, - const String16& packageName, int uid) = 0; - virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags) = 0; - virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids) = 0; + const String16& packageName, int uid, bool isOneWay = false) = 0; + virtual status_t releaseWakeLock(const sp<IBinder>& lock, int flags, bool isOneWay = false) = 0; + virtual status_t updateWakeLockUids(const sp<IBinder>& lock, int len, const int *uids, + bool isOneWay = false) = 0; + // oneway in the .aidl + virtual status_t powerHint(int hintId, int data) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/powermanager/PowerManager.h b/include/powermanager/PowerManager.h index 4590174..cbddc11 100644 --- a/include/powermanager/PowerManager.h +++ b/include/powermanager/PowerManager.h @@ -24,6 +24,14 @@ enum { POWERMANAGER_PARTIAL_WAKE_LOCK = 1, // equals PowerManager.PARTIAL_WAKE_LOCK constant }; +enum { + USER_ACTIVITY_EVENT_OTHER = 0, + USER_ACTIVITY_EVENT_BUTTON = 1, + USER_ACTIVITY_EVENT_TOUCH = 2, + + USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code. +}; + }; // namespace android #endif // ANDROID_POWERMANAGER_H diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index 5584fb1..2fa6ff9 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -113,7 +113,8 @@ struct DisplayState { enum { eSurfaceChanged = 0x01, eLayerStackChanged = 0x02, - eDisplayProjectionChanged = 0x04 + eDisplayProjectionChanged = 0x04, + eDisplaySizeChanged = 0x08 }; uint32_t what; @@ -123,6 +124,7 @@ struct DisplayState { uint32_t orientation; Rect viewport; Rect frame; + uint32_t width, height; status_t write(Parcel& output) const; status_t read(const Parcel& input); }; diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h index 2853e06..799944f 100644 --- a/include/ui/DisplayInfo.h +++ b/include/ui/DisplayInfo.h @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> +#include <utils/Timers.h> #include <ui/PixelFormat.h> @@ -33,7 +34,8 @@ struct DisplayInfo { float density; uint8_t orientation; bool secure; - uint8_t reserved[2]; + nsecs_t appVsyncOffset; + nsecs_t presentationDeadline; }; /* Display orientations as defined in Surface.java and ISurfaceComposer.h. */ diff --git a/include/ui/DisplayStatInfo.h b/include/ui/DisplayStatInfo.h new file mode 100644 index 0000000..0549a83 --- /dev/null +++ b/include/ui/DisplayStatInfo.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_UI_DISPLAY_STAT_INFO_H +#define ANDROID_UI_DISPLAY_STAT_INFO_H + +#include <utils/Timers.h> + +namespace android { + +struct DisplayStatInfo { + nsecs_t vsyncTime; + nsecs_t vsyncPeriod; +}; + +}; // namespace android + +#endif // ANDROID_COMPOSER_DISPLAY_STAT_INFO_H diff --git a/include/ui/FrameStats.h b/include/ui/FrameStats.h new file mode 100644 index 0000000..5fdf94d --- /dev/null +++ b/include/ui/FrameStats.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 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_UI_FRAME_STATS_H +#define ANDROID_UI_FRAME_STATS_H + +#include <utils/Flattenable.h> +#include <utils/Timers.h> +#include <utils/Vector.h> + +namespace android { + +class FrameStats : public LightFlattenable<FrameStats> { +public: + + /* + * Approximate refresh time, in nanoseconds. + */ + nsecs_t refreshPeriodNano; + + /* + * The times in nanoseconds for when the frame contents were posted by the producer (e.g. + * the application). They are either explicitly set or defaulted to the time when + * Surface::queueBuffer() was called. + */ + Vector<nsecs_t> desiredPresentTimesNano; + + /* + * The times in milliseconds for when the frame contents were presented on the screen. + */ + Vector<nsecs_t> actualPresentTimesNano; + + /* + * The times in nanoseconds for when the frame contents were ready to be presented. Note that + * a frame can be posted and still it contents being rendered asynchronously in GL. In such a + * case these are the times when the frame contents were completely rendered (i.e. their fences + * signaled). + */ + Vector<nsecs_t> frameReadyTimesNano; + + // LightFlattenable + bool isFixedSize() const; + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); +}; + +}; // namespace android + +#endif // ANDROID_UI_FRAME_STATS_H diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 5ec738f..5cd8101 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -17,6 +17,8 @@ #ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H #define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H +#warning "FramebufferNativeWindow is deprecated" + #include <stdint.h> #include <sys/types.h> diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 3cf628c..7630faa 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -64,7 +64,9 @@ public: USAGE_HW_2D = GRALLOC_USAGE_HW_2D, USAGE_HW_COMPOSER = GRALLOC_USAGE_HW_COMPOSER, USAGE_HW_VIDEO_ENCODER = GRALLOC_USAGE_HW_VIDEO_ENCODER, - USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK + USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK, + + USAGE_CURSOR = GRALLOC_USAGE_CURSOR, }; GraphicBuffer(); @@ -88,7 +90,8 @@ public: uint32_t getUsage() const { return usage; } PixelFormat getPixelFormat() const { return format; } Rect getBounds() const { return Rect(width, height); } - + uint64_t getId() const { return mId; } + status_t reallocate(uint32_t w, uint32_t h, PixelFormat f, uint32_t usage); status_t lock(uint32_t usage, void** vaddr); @@ -97,6 +100,11 @@ public: status_t lockYCbCr(uint32_t usage, android_ycbcr *ycbcr); status_t lockYCbCr(uint32_t usage, const Rect& rect, android_ycbcr *ycbcr); status_t unlock(); + status_t lockAsync(uint32_t usage, void** vaddr, int fenceFd); + status_t lockAsync(uint32_t usage, const Rect& rect, void** vaddr, int fenceFd); + status_t lockAsyncYCbCr(uint32_t usage, android_ycbcr *ycbcr, int fenceFd); + status_t lockAsyncYCbCr(uint32_t usage, const Rect& rect, android_ycbcr *ycbcr, int fenceFd); + status_t unlockAsync(int *fenceFd); ANativeWindowBuffer* getNativeBuffer() const; @@ -146,6 +154,8 @@ private: // If we're wrapping another buffer then this reference will make sure it // doesn't get freed. sp<ANativeWindowBuffer> mWrappedBuffer; + + uint64_t mId; }; }; // namespace android diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h index 99d8723..98fff0e 100644 --- a/include/ui/GraphicBufferMapper.h +++ b/include/ui/GraphicBufferMapper.h @@ -49,6 +49,14 @@ public: int usage, const Rect& bounds, android_ycbcr *ycbcr); status_t unlock(buffer_handle_t handle); + + status_t lockAsync(buffer_handle_t handle, + int usage, const Rect& bounds, void** vaddr, int fenceFd); + + status_t lockAsyncYCbCr(buffer_handle_t handle, + int usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd); + + status_t unlockAsync(buffer_handle_t handle, int *fenceFd); // dumps information about the mapping of this handle void dump(buffer_handle_t handle); diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h index 627cfb6..7e46945 100644 --- a/include/ui/PixelFormat.h +++ b/include/ui/PixelFormat.h @@ -56,13 +56,15 @@ enum { // real pixel formats supported for rendering ----------------------------- - PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA - PIXEL_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0 - PIXEL_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB - PIXEL_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, // 16-bit RGB - PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA - PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB - PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB + PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA + PIXEL_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0 + PIXEL_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB + PIXEL_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, // 16-bit RGB + PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA + PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB + PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB + PIXEL_FORMAT_sRGB_A_8888 = HAL_PIXEL_FORMAT_sRGB_A_8888, // 4x8-bit sRGB + A + PIXEL_FORMAT_sRGB_X_8888 = HAL_PIXEL_FORMAT_sRGB_X_8888, // 4x8-bit sRGB, no A }; typedef int32_t PixelFormat; diff --git a/include/ui/Region.h b/include/ui/Region.h index d906dbb..0d1c68c 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -50,6 +50,9 @@ public: inline Rect getBounds() const { return mStorage[mStorage.size() - 1]; } inline Rect bounds() const { return getBounds(); } + bool contains(const Point& point) const; + bool contains(int x, int y) const; + // the region becomes its bounds Region& makeBoundsSelf(); diff --git a/include/ui/mat4.h b/include/ui/mat4.h index d9647cc..4fd1eff 100644 --- a/include/ui/mat4.h +++ b/include/ui/mat4.h @@ -322,6 +322,7 @@ tmat44<T> tmat44<T>::rotate(A radian, const tvec3<B>& about) { r[ 1] = xy*nc + zs; r[ 5] = y*y*nc + c; r[ 9] = yz*nc - xs; r[ 2] = zx*nc - ys; r[ 6] = yz*nc + xs; r[10] = z*z*nc + c; } + return rotation; } // ---------------------------------------------------------------------------------------- |