diff options
Diffstat (limited to 'include')
52 files changed, 2455 insertions, 1220 deletions
diff --git a/include/android/configuration.h b/include/android/configuration.h index 0f5c14a..d5cddb3 100644 --- a/include/android/configuration.h +++ b/include/android/configuration.h @@ -44,6 +44,7 @@ enum { ACONFIGURATION_DENSITY_HIGH = 240, ACONFIGURATION_DENSITY_XHIGH = 320, ACONFIGURATION_DENSITY_XXHIGH = 480, + ACONFIGURATION_DENSITY_XXXHIGH = 640, ACONFIGURATION_DENSITY_NONE = 0xffff, ACONFIGURATION_KEYBOARD_ANY = 0x0000, diff --git a/include/android/input.h b/include/android/input.h index 26c4eb8..fead769 100644 --- a/include/android/input.h +++ b/include/android/input.h @@ -428,6 +428,7 @@ enum { enum { AINPUT_SOURCE_CLASS_MASK = 0x000000ff, + AINPUT_SOURCE_CLASS_NONE = 0x00000000, AINPUT_SOURCE_CLASS_BUTTON = 0x00000001, AINPUT_SOURCE_CLASS_POINTER = 0x00000002, AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004, @@ -446,6 +447,7 @@ enum { AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER, AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION, AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION, + AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE, AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK, AINPUT_SOURCE_ANY = 0xffffff00, diff --git a/include/android/keycodes.h b/include/android/keycodes.h index 282e729..cf38d1a 100644 --- a/include/android/keycodes.h +++ b/include/android/keycodes.h @@ -263,6 +263,8 @@ enum { AKEYCODE_RO = 217, AKEYCODE_KANA = 218, AKEYCODE_ASSIST = 219, + AKEYCODE_BRIGHTNESS_DOWN = 220, + AKEYCODE_BRIGHTNESS_UP = 221, // 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/binder/AppOpsManager.h b/include/binder/AppOpsManager.h new file mode 100644 index 0000000..256cb94 --- /dev/null +++ b/include/binder/AppOpsManager.h @@ -0,0 +1,89 @@ +/* + * 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_APP_OPS_MANAGER_H +#define ANDROID_APP_OPS_MANAGER_H + +#include <binder/IAppOpsService.h> + +#include <utils/threads.h> + +// --------------------------------------------------------------------------- +namespace android { + +class AppOpsManager +{ +public: + enum { + MODE_ALLOWED = IAppOpsService::MODE_ALLOWED, + MODE_IGNORED = IAppOpsService::MODE_IGNORED, + MODE_ERRORED = IAppOpsService::MODE_ERRORED + }; + + enum { + OP_NONE = -1, + OP_COARSE_LOCATION = 0, + OP_FINE_LOCATION = 1, + OP_GPS = 2, + OP_VIBRATE = 3, + OP_READ_CONTACTS = 4, + OP_WRITE_CONTACTS = 5, + OP_READ_CALL_LOG = 6, + OP_WRITE_CALL_LOG = 7, + OP_READ_CALENDAR = 8, + OP_WRITE_CALENDAR = 9, + OP_WIFI_SCAN = 10, + OP_POST_NOTIFICATION = 11, + OP_NEIGHBORING_CELLS = 12, + OP_CALL_PHONE = 13, + OP_READ_SMS = 14, + OP_WRITE_SMS = 15, + OP_RECEIVE_SMS = 16, + OP_RECEIVE_EMERGECY_SMS = 17, + OP_RECEIVE_MMS = 18, + OP_RECEIVE_WAP_PUSH = 19, + OP_SEND_SMS = 20, + OP_READ_ICC_SMS = 21, + OP_WRITE_ICC_SMS = 22, + OP_WRITE_SETTINGS = 23, + OP_SYSTEM_ALERT_WINDOW = 24, + OP_ACCESS_NOTIFICATIONS = 25, + OP_CAMERA = 26, + OP_RECORD_AUDIO = 27, + OP_PLAY_AUDIO = 28 + }; + + AppOpsManager(); + + int32_t checkOp(int32_t op, int32_t uid, const String16& callingPackage); + int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage); + int32_t startOp(int32_t op, int32_t uid, const String16& callingPackage); + void finishOp(int32_t op, int32_t uid, const String16& callingPackage); + void startWatchingMode(int32_t op, const String16& packageName, + const sp<IAppOpsCallback>& callback); + void stopWatchingMode(const sp<IAppOpsCallback>& callback); + +private: + Mutex mLock; + sp<IAppOpsService> mService; + + sp<IAppOpsService> getService(); +}; + + +}; // namespace android +// --------------------------------------------------------------------------- +#endif // ANDROID_APP_OPS_MANAGER_H diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h index 6460268..5ac36d9 100644 --- a/include/binder/BinderService.h +++ b/include/binder/BinderService.h @@ -36,13 +36,18 @@ class BinderService public: static status_t publish(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); - return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); + return sm->addService( + String16(SERVICE::getServiceName()), + new SERVICE(), allowIsolated); } static void publishAndJoinThreadPool(bool allowIsolated = false) { sp<IServiceManager> sm(defaultServiceManager()); - sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); + sm->addService( + String16(SERVICE::getServiceName()), + new SERVICE(), allowIsolated); ProcessState::self()->startThreadPool(); + ProcessState::self()->giveThreadPoolName(); IPCThreadState::self()->joinThreadPool(); } diff --git a/include/gui/ISurface.h b/include/binder/IAppOpsCallback.h index c0ff9fc..7f8eb01 100644 --- a/include/gui/ISurface.h +++ b/include/binder/IAppOpsCallback.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * 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. @@ -14,41 +14,31 @@ * limitations under the License. */ -#ifndef ANDROID_GUI_ISURFACE_H -#define ANDROID_GUI_ISURFACE_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/RefBase.h> +// +#ifndef ANDROID_IAPP_OPS_CALLBACK_H +#define ANDROID_IAPP_OPS_CALLBACK_H #include <binder/IInterface.h> -#include <ui/PixelFormat.h> - namespace android { -typedef int32_t SurfaceID; +// ---------------------------------------------------------------------- -class ISurfaceTexture; - -class ISurface : public IInterface +class IAppOpsCallback : public IInterface { -protected: - enum { - GET_SURFACE_TEXTURE = IBinder::FIRST_CALL_TRANSACTION, - }; +public: + DECLARE_META_INTERFACE(AppOpsCallback); -public: - DECLARE_META_INTERFACE(Surface); + virtual void opChanged(int32_t op, const String16& packageName) = 0; - virtual sp<ISurfaceTexture> getSurfaceTexture() const = 0; + enum { + OP_CHANGED_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + }; }; -// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------- -class BnSurface : public BnInterface<ISurface> +class BnAppOpsCallback : public BnInterface<IAppOpsCallback> { public: virtual status_t onTransact( uint32_t code, @@ -57,8 +47,9 @@ public: uint32_t flags = 0); }; -// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------- }; // namespace android -#endif // ANDROID_GUI_ISURFACE_H +#endif // ANDROID_IAPP_OPS_CALLBACK_H + diff --git a/include/binder/IAppOpsService.h b/include/binder/IAppOpsService.h new file mode 100644 index 0000000..7cb55e5 --- /dev/null +++ b/include/binder/IAppOpsService.h @@ -0,0 +1,72 @@ +/* + * 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_IAPP_OPS_SERVICE_H +#define ANDROID_IAPP_OPS_SERVICE_H + +#include <binder/IAppOpsCallback.h> +#include <binder/IInterface.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class IAppOpsService : public IInterface +{ +public: + DECLARE_META_INTERFACE(AppOpsService); + + virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual int32_t startOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual void finishOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual void startWatchingMode(int32_t op, const String16& packageName, + const sp<IAppOpsCallback>& callback) = 0; + virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0; + + enum { + CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + NOTE_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+1, + START_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+2, + FINISH_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+3, + START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4, + STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5 + }; + + enum { + MODE_ALLOWED = 0, + MODE_IGNORED = 1, + MODE_ERRORED = 2 + }; +}; + +// ---------------------------------------------------------------------- + +class BnAppOpsService : public BnInterface<IAppOpsService> +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAPP_OPS_SERVICE_H diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h index 8caf1af..e63a0d0 100644 --- a/include/binder/ProcessState.h +++ b/include/binder/ProcessState.h @@ -71,6 +71,7 @@ public: void spawnPooledThread(bool isMain); status_t setThreadPoolMaxThreadCount(size_t maxThreads); + void giveThreadPoolName(); private: friend class IPCThreadState; @@ -80,6 +81,7 @@ private: ProcessState(const ProcessState& o); ProcessState& operator=(const ProcessState& o); + String8 makeBinderThreadName(); struct handle_entry { IBinder* binder; diff --git a/include/diskusage/dirsize.h b/include/diskusage/dirsize.h new file mode 100644 index 0000000..34236c0 --- /dev/null +++ b/include/diskusage/dirsize.h @@ -0,0 +1,30 @@ +/* + * + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIBDISKUSAGE_DIRSIZE_H +#define __LIBDISKUSAGE_DIRSIZE_H + +#include <stdint.h> + +__BEGIN_DECLS + +int64_t stat_size(struct stat *s); +int64_t calculate_dir_size(int dfd); + +__END_DECLS + +#endif /* __LIBDISKUSAGE_DIRSIZE_H */ diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h index cd4df25..98b450c 100644 --- a/include/gui/BufferItemConsumer.h +++ b/include/gui/BufferItemConsumer.h @@ -82,8 +82,16 @@ class BufferItemConsumer: public ConsumerBase status_t releaseBuffer(const BufferItem &item, const sp<Fence>& releaseFence = Fence::NO_FENCE); - sp<ISurfaceTexture> getProducerInterface() const { return getBufferQueue(); } + sp<IGraphicBufferProducer> getProducerInterface() const { return getBufferQueue(); } + // setDefaultBufferSize is used to set the size of buffers returned by + // requestBuffers when a with and height of zero is requested. + status_t setDefaultBufferSize(uint32_t w, uint32_t h); + + // setDefaultBufferFormat allows the BufferQueue to create + // GraphicBuffers of a defaultFormat if no format is specified + // in dequeueBuffer + status_t setDefaultBufferFormat(uint32_t defaultFormat); }; } // namespace android diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index 9e265ba..6c1b691 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -21,7 +21,7 @@ #include <EGL/eglext.h> #include <gui/IGraphicBufferAlloc.h> -#include <gui/ISurfaceTexture.h> +#include <gui/IGraphicBufferProducer.h> #include <ui/Fence.h> #include <ui/GraphicBuffer.h> @@ -33,7 +33,7 @@ namespace android { // ---------------------------------------------------------------------------- -class BufferQueue : public BnSurfaceTexture { +class BufferQueue : public BnGraphicBufferProducer { public: enum { MIN_UNDEQUEUED_BUFFERS = 2 }; enum { NUM_BUFFER_SLOTS = 32 }; @@ -48,7 +48,7 @@ public: // ConsumerListener is the interface through which the BufferQueue notifies // the consumer of events that the consumer may wish to react to. Because // the consumer will generally have a mutex that is locked during calls from - // teh consumer to the BufferQueue, these calls from the BufferQueue to the + // the consumer to the BufferQueue, these calls from the BufferQueue to the // consumer *MUST* be called only when the BufferQueue mutex is NOT locked. struct ConsumerListener : public virtual RefBase { // onFrameAvailable is called from queueBuffer each time an additional @@ -104,66 +104,127 @@ public: const sp<IGraphicBufferAlloc>& allocator = NULL); virtual ~BufferQueue(); + // 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. After - // calling this all buffer slots are both unallocated and owned by the - // BufferQueue object (i.e. they are not owned by the client). + // 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 client 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 + // 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 NULL, the buffer may be written - // immediately. + // 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. - virtual status_t dequeueBuffer(int *buf, sp<Fence>& fence, + // 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, uint32_t width, uint32_t height, uint32_t format, uint32_t usage); - // queueBuffer returns a filled buffer to the BufferQueue. In addition, a - // timestamp must be provided for the buffer. The timestamp is in + // 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 client-dependent and should be documented by the - // client. + // (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); - virtual void cancelBuffer(int buf, sp<Fence> fence); + // 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); - // setSynchronousMode set whether dequeueBuffer is synchronous or + // setSynchronousMode sets whether dequeueBuffer is synchronous or // asynchronous. In synchronous mode, dequeueBuffer blocks until // a buffer is available, the currently bound buffer can be dequeued and - // queued buffers will be retired in order. + // queued buffers will be acquired in order. In asynchronous mode, + // a queued buffer may be replaced by a subsequently queued buffer. + // // The default mode is asynchronous. virtual status_t setSynchronousMode(bool enabled); - // connect attempts to connect a producer client API to the BufferQueue. - // This must be called before any other ISurfaceTexture methods are called - // except for getAllocator. + // 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). // - // This method will fail if the connect was previously called on the - // BufferQueue and no corresponding disconnect call was made. + // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU). virtual status_t connect(int api, QueueBufferOutput* output); - // disconnect attempts to disconnect a producer client API from the - // BufferQueue. Calling this method will cause any subsequent calls to other - // ISurfaceTexture methods to fail except for getAllocator and connect. + // 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 client API. + // connected to the specified producer API. virtual status_t disconnect(int api); // dump our state in a String @@ -181,9 +242,10 @@ public: mFrameNumber(0), mBuf(INVALID_BUFFER_SLOT) { mCrop.makeInvalid(); - } - // mGraphicBuffer points to the buffer allocated for this slot or is NULL - // if no buffer has been allocated. + } + // 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; // mCrop is the current crop rectangle for this buffer slot. @@ -209,7 +271,7 @@ public: sp<Fence> mFence; }; - // The following public functions is the consumer facing interface + // The following public functions are the consumer-facing 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 @@ -221,7 +283,9 @@ public: status_t acquireBuffer(BufferItem *buffer); // releaseBuffer releases a buffer slot from the consumer back to the - // BufferQueue pending a fence sync. + // 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. // // 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 @@ -237,6 +301,8 @@ public: // 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. + // + // consumer may not be NULL. status_t consumerConnect(const sp<ConsumerListener>& consumer); // consumerDisconnect disconnects a consumer from the BufferQueue. All @@ -246,25 +312,31 @@ public: status_t consumerDisconnect(); // getReleasedBuffers sets the value pointed to by slotMask to a bit mask - // indicating which buffer slots the have been released by the BufferQueue + // 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. status_t getReleasedBuffers(uint32_t* slotMask); // setDefaultBufferSize is used to set the size of buffers returned by - // requestBuffers when a with and height of zero is requested. + // dequeueBuffer when a width and height of zero is requested. Default + // is 1x1. status_t setDefaultBufferSize(uint32_t w, uint32_t h); - // setDefaultBufferCount set the buffer count. If the client has requested - // a buffer count using setBufferCount, the server-buffer count will - // take effect once the client sets the count back to zero. + // 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. status_t setDefaultMaxBufferCount(int bufferCount); // setMaxAcquiredBufferCount sets the maximum number of buffers that can - // be acquired by the consumer at one time. This call will fail if a - // producer is connected to the BufferQueue. + // be acquired by the consumer at one time (default 1). This call will + // fail if a producer is connected to the BufferQueue. status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); - // isSynchronousMode returns whether the SurfaceTexture is currently in + // isSynchronousMode returns whether the BufferQueue is currently in // synchronous mode. bool isSynchronousMode() const; @@ -273,41 +345,48 @@ public: // setDefaultBufferFormat allows the BufferQueue to create // GraphicBuffers of a defaultFormat if no format is specified - // in dequeueBuffer + // in dequeueBuffer. Formats are enumerated in graphics.h; the + // initial default is HAL_PIXEL_FORMAT_RGBA_8888. status_t setDefaultBufferFormat(uint32_t defaultFormat); - // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer + // 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. status_t setConsumerUsageBits(uint32_t usage); - // setTransformHint bakes in rotation to buffers so overlays can be used + // 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). status_t setTransformHint(uint32_t hint); private: - // freeBufferLocked frees the resources (both GraphicBuffer and EGLImage) - // for the given slot. + // freeBufferLocked frees the GraphicBuffer and sync resources for the + // given slot. void freeBufferLocked(int index); - // freeAllBuffersLocked frees the resources (both GraphicBuffer and - // EGLImage) for all slots. + // freeAllBuffersLocked frees the GraphicBuffer and sync resources for + // all slots. void freeAllBuffersLocked(); - // freeAllBuffersExceptHeadLocked frees the resources (both GraphicBuffer - // and EGLImage) for all slots except the head of mQueue + // freeAllBuffersExceptHeadLocked frees the GraphicBuffer and sync + // resources for all slots except the head of mQueue. void freeAllBuffersExceptHeadLocked(); - // drainQueueLocked drains the buffer queue if we're in synchronous mode - // returns immediately otherwise. It returns NO_INIT if the BufferQueue - // became abandoned or disconnected during this call. + // drainQueueLocked waits for the buffer queue to empty if we're in + // synchronous mode, or returns immediately otherwise. It returns NO_INIT + // if the BufferQueue is abandoned (consumer disconnected) or disconnected + // (producer disconnected) during the call. status_t drainQueueLocked(); // drainQueueAndFreeBuffersLocked drains the buffer queue if we're in // synchronous mode and free all buffers. In asynchronous mode, all buffers - // are freed except the current buffer. + // are freed except the currently queued buffer (if it exists). status_t drainQueueAndFreeBuffersLocked(); // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots // that will be used if the producer does not override the buffer slot - // count. + // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. + // The initial default is 2. status_t setDefaultMaxBufferCountLocked(int count); // getMinBufferCountLocked returns the minimum number of buffers allowed @@ -351,51 +430,56 @@ private: // if no buffer has been allocated. sp<GraphicBuffer> mGraphicBuffer; - // mEglDisplay is the EGLDisplay used to create mEglImage. + // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects. EGLDisplay mEglDisplay; // BufferState represents the different states in which a buffer slot - // can be. + // can be. All slots are initially FREE. enum BufferState { - // FREE indicates that the buffer is not currently being used and - // will not be used in the future until it gets dequeued and - // subsequently queued by the client. - // aka "owned by BufferQueue, ready to be dequeued" + // 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 - // client, but has not yet been queued or canceled. The buffer is - // considered 'owned' by the client, and the server should not use - // it for anything. + // 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. // - // Note that when in synchronous-mode (mSynchronousMode == true), - // the buffer that's currently attached to the texture may be - // dequeued by the client. That means that the current buffer can - // be in either the DEQUEUED or QUEUED state. In asynchronous mode, - // however, the current buffer is always in the QUEUED state. - // aka "owned by producer, ready to be queued" + // 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 queued by the client, - // and has not since been made available for the client to dequeue. - // Attaching the buffer to the texture does NOT transition the - // buffer away from the QUEUED state. However, in Synchronous mode - // the current buffer may be dequeued by the client under some - // circumstances. See the note about the current buffer in the - // documentation for DEQUEUED. - // aka "owned by BufferQueue, ready to be acquired" + // 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, - // aka "owned by consumer, ready to be released" + // 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 client did + // 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 client bugs. + // needed but useful for debugging and catching producer bugs. bool mRequestBufferCalled; // mCrop is the current crop rectangle for this buffer slot. @@ -413,13 +497,16 @@ private: // to set by queueBuffer each time this slot is queued. int64_t mTimestamp; - // mFrameNumber is the number of the queued frame for this slot. + // 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 (optionally, based - // on a compile-time option) set to a new sync object in updateTexImage. + // 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 @@ -430,29 +517,32 @@ private: // 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 empty. + // 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 consumer + // 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 client - // side. This allows buffer ownership to be transferred between the client - // and server 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. + // 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 requestBuffers() if a width and height of zero is specified. + // 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 requestBuffers() if a width and height of zero is specified. + // in dequeueBuffer() if a width and height of zero is specified. uint32_t mDefaultHeight; // mMaxAcquiredBufferCount is the number of buffers that the consumer may @@ -489,12 +579,13 @@ private: // mSynchronousMode whether we're in synchronous mode or not bool mSynchronousMode; - // mAllowSynchronousMode whether we allow synchronous mode or not + // mAllowSynchronousMode whether we allow synchronous mode or not. Set + // when the BufferQueue is created (by the consumer). const bool mAllowSynchronousMode; - // mConnectedApi indicates the API that is currently connected to this - // BufferQueue. It defaults to NO_CONNECTED_API (= 0), and gets updated - // by the connect and disconnect methods. + // 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 @@ -505,14 +596,15 @@ private: Fifo mQueue; // mAbandoned indicates that the BufferQueue will no longer be used to - // consume images buffers pushed to it using the ISurfaceTexture interface. - // It is initialized to false, and set to true in the abandon method. A - // BufferQueue that has been abandoned will return the NO_INIT error from - // all ISurfaceTexture methods capable of returning an error. + // 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; - // mName is a string used to identify the BufferQueue in log messages. - // It is set by the setName method. + // 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 @@ -520,12 +612,13 @@ private: // member variables are accessed. mutable Mutex mMutex; - // mFrameCounter is the free running counter, incremented for every buffer queued - // with the surface Texture. + // mFrameCounter is the free running counter, incremented on every + // successful queueBuffer call. uint64_t mFrameCounter; - // mBufferHasBeenQueued is true once a buffer has been queued. It is reset - // by changing the buffer count. + // 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 diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h index ee5cb29..8a7545d 100644 --- a/include/gui/ConsumerBase.h +++ b/include/gui/ConsumerBase.h @@ -53,7 +53,7 @@ public: // abandon frees all the buffers and puts the ConsumerBase into the // 'abandoned' state. Once put in this state the ConsumerBase can never // leave it. When in the 'abandoned' state, all methods of the - // ISurfaceTexture interface will fail with the NO_INIT error. + // IGraphicBufferProducer interface will fail with the NO_INIT error. // // Note that while calling this method causes all the buffers to be freed // from the perspective of the the ConsumerBase, if there are additional @@ -69,16 +69,15 @@ public: // ConsumerBase is connected. sp<BufferQueue> getBufferQueue() const; - // dump writes the current state to a string. These methods should NOT be - // overridden by child classes. Instead they should override the - // dumpLocked method, which is called by these methods after locking the - // mutex. + // dump writes the current state to a string. Child classes should add + // their state to the dump by overriding the dumpLocked method, which is + // called by these methods after locking the mutex. void dump(String8& result) const; void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const; // setFrameAvailableListener sets the listener object that will be notified // when a new frame becomes available. - void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); + void setFrameAvailableListener(const wp<FrameAvailableListener>& listener); private: ConsumerBase(const ConsumerBase&); @@ -90,6 +89,18 @@ protected: // buffers from the given BufferQueue. ConsumerBase(const sp<BufferQueue> &bufferQueue); + // onLastStrongRef gets called by RefBase just before the dtor of the most + // derived class. It is used to clean up the buffers so that ConsumerBase + // can coordinate the clean-up by calling into virtual methods implemented + // by the derived classes. This would not be possible from the + // ConsuemrBase dtor because by the time that gets called the derived + // classes have already been destructed. + // + // This methods should not need to be overridden by derived classes, but + // if they are overridden the ConsumerBase implementation must be called + // from the derived class. + virtual void onLastStrongRef(const void* id); + // Implementation of the BufferQueue::ConsumerListener 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 @@ -186,7 +197,7 @@ protected: Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS]; // mAbandoned indicates that the BufferQueue will no longer be used to - // consume images buffers pushed to it using the ISurfaceTexture + // consume images buffers pushed to it using the IGraphicBufferProducer // interface. It is initialized to false, and set to true in the abandon // method. A BufferQueue that has been abandoned will return the NO_INIT // error from all IConsumerBase methods capable of returning an error. @@ -199,7 +210,7 @@ protected: // mFrameAvailableListener is the listener object that will be called when a // new frame becomes available. If it is not NULL it will be called from // queueBuffer. - sp<FrameAvailableListener> mFrameAvailableListener; + wp<FrameAvailableListener> mFrameAvailableListener; // The ConsumerBase has-a BufferQueue and is responsible for creating this object // if none is supplied diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h index 807a4b5..bf9918e 100644 --- a/include/gui/CpuConsumer.h +++ b/include/gui/CpuConsumer.h @@ -37,7 +37,7 @@ namespace android { * This queue is synchronous by default. */ -class CpuConsumer: public ConsumerBase +class CpuConsumer : public ConsumerBase { public: typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; @@ -53,11 +53,19 @@ class CpuConsumer: public ConsumerBase uint32_t scalingMode; int64_t timestamp; uint64_t frameNumber; + // Values below are only valid when using + // HAL_PIXEL_FORMAT_YCbCr_420_888, in which case LockedBuffer::data + // contains the Y channel, and stride is the Y channel stride. For other + // formats, these will all be 0. + uint8_t *dataCb; + uint8_t *dataCr; + uint32_t chromaStride; + uint32_t chromaStep; }; // Create a new CPU consumer. The maxLockedBuffers parameter specifies // how many buffers can be locked for user access at the same time. - CpuConsumer(uint32_t maxLockedBuffers); + CpuConsumer(uint32_t maxLockedBuffers, bool synchronousMode = true); virtual ~CpuConsumer(); @@ -82,17 +90,32 @@ class CpuConsumer: public ConsumerBase // lockNextBuffer. status_t unlockBuffer(const LockedBuffer &nativeBuffer); - sp<ISurfaceTexture> getProducerInterface() const { return getBufferQueue(); } + sp<IGraphicBufferProducer> getProducerInterface() const { return getBufferQueue(); } private: // Maximum number of buffers that can be locked at a time uint32_t mMaxLockedBuffers; + status_t releaseAcquiredBufferLocked(int lockedIdx); + virtual void freeBufferLocked(int slotIndex); - // Array for tracking pointers passed to the consumer, matching the - // mSlots indexing - void *mBufferPointers[BufferQueue::NUM_BUFFER_SLOTS]; + // Tracking for buffers acquired by the user + struct AcquiredBuffer { + // Need to track the original mSlot index and the buffer itself because + // the mSlot entry may be freed/reused before the acquired buffer is + // released. + int mSlot; + sp<GraphicBuffer> mGraphicBuffer; + void *mBufferPointer; + + AcquiredBuffer() : + mSlot(BufferQueue::INVALID_BUFFER_SLOT), + mBufferPointer(NULL) { + } + }; + Vector<AcquiredBuffer> mAcquiredBuffers; + // Count of currently locked buffers uint32_t mCurrentLockedBuffers; diff --git a/include/gui/DummyConsumer.h b/include/gui/DummyConsumer.h index 7fe4d40..08e8ec8 100644 --- a/include/gui/DummyConsumer.h +++ b/include/gui/DummyConsumer.h @@ -24,7 +24,7 @@ namespace android { // The DummyConsumer does not keep a reference to BufferQueue -// unlike SurfaceTexture. This prevents a circular reference from +// unlike GLConsumer. This prevents a circular reference from // forming without having to use a ProxyConsumerListener class DummyConsumer : public BufferQueue::ConsumerListener { public: @@ -33,7 +33,7 @@ public: protected: // Implementation of the BufferQueue::ConsumerListener interface. These - // calls are used to notify the SurfaceTexture of asynchronous events in the + // calls are used to notify the GLConsumer of asynchronous events in the // BufferQueue. virtual void onFrameAvailable(); virtual void onBuffersReleased(); diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h index d53b04a..1ef54f5 100644 --- a/include/gui/GLConsumer.h +++ b/include/gui/GLConsumer.h @@ -17,30 +17,414 @@ #ifndef ANDROID_GUI_CONSUMER_H #define ANDROID_GUI_CONSUMER_H +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <gui/IGraphicBufferProducer.h> #include <gui/BufferQueue.h> #include <gui/ConsumerBase.h> -#include <gui/ISurfaceTexture.h> + +#include <ui/GraphicBuffer.h> + +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/threads.h> + +#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" +#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \ + "mFrameAvailableListener" namespace android { +// ---------------------------------------------------------------------------- + +class String8; + +/* + * GLConsumer consumes buffers of graphics data from a BufferQueue, + * and makes them available to OpenGL as a texture. + * + * A typical usage pattern is to set up the GLConsumer with the + * desired options, and call updateTexImage() when a new frame is desired. + * If a new frame is available, the texture will be updated. If not, + * the previous contents are retained. + * + * By default, the texture is attached to the GL_TEXTURE_EXTERNAL_OES + * texture target, in the EGL context of the first thread that calls + * updateTexImage(). + * + * This class was previously called SurfaceTexture. + */ class GLConsumer : public ConsumerBase { public: - GLConsumer(GLuint, bool = false, GLenum = 0, bool = false, const sp<BufferQueue>& = 0) : - ConsumerBase(0) {} - void incStrong(const void*) const {} - void decStrong(const void*) const {} - status_t updateTexImage() { return 0; } - void abandon() {} - sp<ISurfaceTexture> getBufferQueue() const { return 0; } - GLenum getCurrentTextureTarget() const { return 0; } - status_t setSynchronousMode(bool) { return 0; } - void getTransformMatrix(float[16]) {} - int64_t getTimestamp() {} - void setFrameAvailableListener(const wp<FrameAvailableListener>&) {} - sp<GraphicBuffer> getCurrentBuffer() const { return 0; } + 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. + // + // A GLConsumer may be detached from one OpenGL ES context and then + // attached to a different context using the detachFromContext and + // attachToContext methods, respectively. The intention of these methods is + // purely to allow a GLConsumer to be transferred from one consumer + // context to another. If such a transfer is not needed there is no + // requirement that either of these methods be called. + GLConsumer(const sp<BufferQueue>& bq, + GLuint tex, GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, + bool useFenceSync = true); + GLConsumer(GLuint tex, bool allowSynchronousMode = true, + GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true, + const sp<BufferQueue> &bufferQueue = 0); + + // updateTexImage acquires the most recently queued buffer, and sets the + // image contents of the target texture to it. + // + // This call may only be made while the OpenGL ES context to which the + // target texture belongs is bound to the calling thread. + // + // This calls doGLFenceWait to ensure proper synchronization. + status_t updateTexImage(); + + // setReleaseFence stores a fence that will signal when the current buffer + // is no longer being read. This fence will be returned to the producer + // when the current buffer is released by updateTexImage(). Multiple + // fences can be set for a given buffer; they will be merged into a single + // union fence. + void setReleaseFence(const sp<Fence>& fence); + + // setDefaultMaxBufferCount sets the default limit on the maximum number + // of buffers that will be allocated at one time. The image producer may + // override the limit. + status_t setDefaultMaxBufferCount(int bufferCount); + + // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix + // associated with the texture image set by the most recent call to + // updateTexImage. + // + // This transform matrix maps 2D homogeneous texture coordinates of the form + // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture + // coordinate that should be used to sample that location from the texture. + // Sampling the texture outside of the range of this transform is undefined. + // + // This transform is necessary to compensate for transforms that the stream + // content producer may implicitly apply to the content. By forcing users of + // a GLConsumer to apply this transform we avoid performing an extra + // copy of the data that would be needed to hide the transform from the + // user. + // + // The matrix is stored in column-major order so that it may be passed + // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv + // functions. + void getTransformMatrix(float mtx[16]); + + // getTimestamp retrieves the timestamp associated with the texture image + // set by the most recent call to updateTexImage. + // + // The timestamp is in nanoseconds, and is monotonically increasing. Its + // other semantics (zero point, etc) are source-dependent and should be + // documented by the source. + int64_t getTimestamp(); + + // setDefaultBufferSize is used to set the size of buffers returned by + // requestBuffers when a with and height of zero is requested. + // A call to setDefaultBufferSize() may trigger requestBuffers() to + // be called from the client. + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. + status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // setFilteringEnabled sets whether the transform matrix should be computed + // for use with bilinear filtering. + void setFilteringEnabled(bool enabled); + + // getCurrentBuffer returns the buffer associated with the current image. + sp<GraphicBuffer> getCurrentBuffer() const; + + // getCurrentTextureTarget returns the texture target of the current + // texture as returned by updateTexImage(). + GLenum getCurrentTextureTarget() const; + + // getCurrentCrop returns the cropping rectangle of the current buffer. + Rect getCurrentCrop() const; + + // getCurrentTransform returns the transform of the current buffer. + uint32_t getCurrentTransform() const; + + // getCurrentScalingMode returns the scaling mode of the current buffer. + uint32_t getCurrentScalingMode() const; + + // getCurrentFence returns the fence indicating when the current buffer is + // ready to be read from. + sp<Fence> getCurrentFence() const; + + // doGLFenceWait inserts a wait command into the OpenGL ES command stream + // to ensure that it is safe for future OpenGL ES commands to access the + // current texture buffer. + status_t doGLFenceWait() const; + + // isSynchronousMode returns whether the GLConsumer is currently in + // synchronous mode. + bool isSynchronousMode() const; + + // set the name of the GLConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // These functions call the corresponding BufferQueue implementation + // so the refactoring can proceed smoothly + status_t setDefaultBufferFormat(uint32_t defaultFormat); + status_t setConsumerUsageBits(uint32_t usage); + status_t setTransformHint(uint32_t hint); + virtual status_t setSynchronousMode(bool enabled); + + // getBufferQueue returns the BufferQueue object to which this + // GLConsumer is connected. + sp<BufferQueue> getBufferQueue() const { + return mBufferQueue; + } + + // detachFromContext detaches the GLConsumer from the calling thread's + // current OpenGL ES context. This context must be the same as the context + // that was current for previous calls to updateTexImage. + // + // Detaching a GLConsumer from an OpenGL ES context will result in the + // deletion of the OpenGL ES texture object into which the images were being + // streamed. After a GLConsumer has been detached from the OpenGL ES + // context calls to updateTexImage will fail returning INVALID_OPERATION + // until the GLConsumer is attached to a new OpenGL ES context using the + // attachToContext method. + status_t detachFromContext(); + + // attachToContext attaches a GLConsumer that is currently in the + // 'detached' state to the current OpenGL ES context. A GLConsumer is + // in the 'detached' state iff detachFromContext has successfully been + // called and no calls to attachToContext have succeeded since the last + // detachFromContext call. Calls to attachToContext made on a + // GLConsumer that is not in the 'detached' state will result in an + // INVALID_OPERATION error. + // + // The tex argument specifies the OpenGL ES texture object name in the + // new context into which the image contents will be streamed. A successful + // call to attachToContext will result in this texture object being bound to + // the texture target and populated with the image contents that were + // current at the time of the last call to detachFromContext. + status_t attachToContext(GLuint tex); + +protected: + + // abandonLocked overrides the ConsumerBase method to clear + // mCurrentTextureBuf in addition to the ConsumerBase behavior. + virtual void abandonLocked(); + + // dumpLocked overrides the ConsumerBase method to dump GLConsumer- + // specific info in addition to the ConsumerBase behavior. + virtual void dumpLocked(String8& result, const char* prefix, char* buffer, + size_t size) const; + + // acquireBufferLocked overrides the ConsumerBase method to update the + // mEglSlots array in addition to the ConsumerBase behavior. + virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item); + + // releaseBufferLocked overrides the ConsumerBase method to update the + // mEglSlots array in addition to the ConsumerBase. + virtual status_t releaseBufferLocked(int buf, EGLDisplay display, + EGLSyncKHR eglFence); + + status_t releaseBufferLocked(int buf, EGLSyncKHR eglFence) { + return releaseBufferLocked(buf, mEglDisplay, eglFence); + } + + static bool isExternalFormat(uint32_t format); + + // This releases the buffer in the slot referenced by mCurrentTexture, + // then updates state to refer to the BufferItem, which must be a + // newly-acquired buffer. + status_t releaseAndUpdateLocked(const BufferQueue::BufferItem& item); + + // Binds mTexName and the current buffer to mTexTarget. Uses + // mCurrentTexture if it's set, mCurrentTextureBuf if not. If the + // bind succeeds, this calls doGLFenceWait. + status_t bindTextureImageLocked(); + + // Gets the current EGLDisplay and EGLContext values, and compares them + // to mEglDisplay and mEglContext. If the fields have been previously + // set, the values must match; if not, the fields are set to the current + // values. + status_t checkAndUpdateEglStateLocked(); + +private: + // createImage creates a new EGLImage from a GraphicBuffer. + EGLImageKHR createImage(EGLDisplay dpy, + const sp<GraphicBuffer>& graphicBuffer); + + // freeBufferLocked frees up the given buffer slot. If the slot has been + // initialized this will release the reference to the GraphicBuffer in that + // slot and destroy the EGLImage in that slot. Otherwise it has no effect. + // + // This method must be called with mMutex locked. + virtual void freeBufferLocked(int slotIndex); + + // computeCurrentTransformMatrixLocked computes the transform matrix for the + // current texture. It uses mCurrentTransform and the current GraphicBuffer + // to compute this matrix and stores it in mCurrentTransformMatrix. + // mCurrentTextureBuf must not be NULL. + void computeCurrentTransformMatrixLocked(); + + // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command + // stream to ensure that it is safe for future OpenGL ES commands to + // access the current texture buffer. + status_t doGLFenceWaitLocked() const; + + // syncForReleaseLocked performs the synchronization needed to release the + // current slot from an OpenGL ES context. If needed it will set the + // current slot's fence to guard against a producer accessing the buffer + // before the outstanding accesses have completed. + status_t syncForReleaseLocked(EGLDisplay dpy); + + // 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); + + // The default consumer usage flags that GLConsumer always sets on its + // BufferQueue instance; these will be OR:d with any additional flags passed + // from the GLConsumer user. In particular, GLConsumer will always + // consume buffers as hardware textures. + static const uint32_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; + + // mCurrentTextureBuf is the graphic 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; + + // mCurrentCrop is the crop rectangle that applies to the current texture. + // It gets set each time updateTexImage is called. + Rect mCurrentCrop; + + // mCurrentTransform is the transform identifier for the current texture. It + // gets set each time updateTexImage is called. + uint32_t mCurrentTransform; + + // mCurrentScalingMode is the scaling mode for the current texture. It gets + // set each time updateTexImage is called. + uint32_t mCurrentScalingMode; + + // mCurrentFence is the fence received from BufferQueue in updateTexImage. + sp<Fence> mCurrentFence; + + // mCurrentTransformMatrix is the transform matrix for the current texture. + // It gets computed by computeTransformMatrix each time updateTexImage is + // called. + float mCurrentTransformMatrix[16]; + + // mCurrentTimestamp is the timestamp for the current texture. It + // gets set each time updateTexImage is called. + int64_t mCurrentTimestamp; + + uint32_t mDefaultWidth, mDefaultHeight; + + // mFilteringEnabled indicates whether the transform matrix is computed for + // use with bilinear filtering. It defaults to true and is changed by + // setFilteringEnabled(). + bool mFilteringEnabled; + + // mTexName is the name of the OpenGL texture to which streamed images will + // be bound when updateTexImage is called. It is set at construction time + // and can be changed with a call to attachToContext. + GLuint mTexName; + + // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync + // extension should be used to prevent buffers from being dequeued before + // it's safe for them to be written. It gets set at construction time and + // never changes. + const bool mUseFenceSync; + + // mTexTarget is the GL texture target with which the GL texture object is + // associated. It is set in the constructor and never changed. It is + // almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android + // Browser. In that case it is set to GL_TEXTURE_2D to allow + // glCopyTexSubImage to read from the texture. This is a hack to work + // around a GL driver limitation on the number of FBO attachments, which the + // browser's tile cache exceeds. + const GLenum mTexTarget; + + // 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) { + } + + // mEglImage is the EGLImage created from mGraphicBuffer. + EGLImageKHR mEglImage; + + // mFence is the EGL sync object that must signal before the buffer + // associated with this buffer slot may be dequeued. It is initialized + // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based + // on a compile-time option) set to a new sync object in updateTexImage. + EGLSyncKHR mEglFence; + }; + + // mEglDisplay is the EGLDisplay with which this GLConsumer is currently + // associated. It is intialized to EGL_NO_DISPLAY and gets set to the + // current display when updateTexImage is called for the first time and when + // attachToContext is called. + EGLDisplay mEglDisplay; + + // mEglContext is the OpenGL ES context with which this GLConsumer is + // currently associated. It is initialized to EGL_NO_CONTEXT and gets set + // to the current GL context when updateTexImage is called for the first + // time and when attachToContext is called. + EGLContext mEglContext; + + // mEGLSlots stores the buffers that have been allocated by the BufferQueue + // for each buffer slot. It is initialized to null pointers, and gets + // filled in with the result of BufferQueue::acquire when the + // client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + EglSlot mEglSlots[BufferQueue::NUM_BUFFER_SLOTS]; + + // mCurrentTexture is the buffer slot index of the buffer that is currently + // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT, + // indicating that no buffer slot is currently bound to the texture. Note, + // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean + // that no buffer is bound to the texture. A call to setBufferCount will + // reset mCurrentTexture to INVALID_BUFFER_SLOT. + int mCurrentTexture; + + // mAttached indicates whether the ConsumerBase is currently attached to + // an OpenGL ES context. For legacy reasons, this is initialized to true, + // indicating that the ConsumerBase is considered to be attached to + // whatever context is current at the time of the first updateTexImage call. + // It is set to false by detachFromContext, and then set to true again by + // attachToContext. + bool mAttached; }; +// ---------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_GUI_CONSUMER_H - diff --git a/include/gui/GraphicBufferAlloc.h b/include/gui/GraphicBufferAlloc.h new file mode 100644 index 0000000..b08750c --- /dev/null +++ b/include/gui/GraphicBufferAlloc.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H +#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H + +#include <stdint.h> +#include <sys/types.h> + +#include <gui/IGraphicBufferAlloc.h> +#include <ui/PixelFormat.h> +#include <utils/Errors.h> + +namespace android { +// --------------------------------------------------------------------------- + +class GraphicBuffer; + +class GraphicBufferAlloc : public BnGraphicBufferAlloc { +public: + GraphicBufferAlloc(); + virtual ~GraphicBufferAlloc(); + virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, + PixelFormat format, uint32_t usage, status_t* error); +}; + + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H diff --git a/include/gui/ISurfaceTexture.h b/include/gui/IGraphicBufferProducer.h index ae7c5c2..29c7ff3 100644 --- a/include/gui/ISurfaceTexture.h +++ b/include/gui/IGraphicBufferProducer.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ANDROID_GUI_ISURFACETEXTURE_H -#define ANDROID_GUI_ISURFACETEXTURE_H +#ifndef ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H +#define ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H #include <stdint.h> #include <sys/types.h> @@ -32,12 +32,26 @@ namespace android { // ---------------------------------------------------------------------------- -class SurfaceTextureClient; +class Surface; -class ISurfaceTexture : public IInterface +/* + * This class defines the Binder IPC interface for the producer side of + * a queue of graphics buffers. It's used to send graphics data from one + * component to another. For example, a class that decodes video for + * playback might use this to provide frames. This is typically done + * indirectly, through Surface. + * + * The underlying mechanism is a BufferQueue, which implements + * BnGraphicBufferProducer. In normal operation, the producer calls + * dequeueBuffer() to get an empty buffer, fills it with data, then + * calls queueBuffer() to make it available to the consumer. + * + * This class was previously called ISurfaceTexture. + */ +class IGraphicBufferProducer : public IInterface { public: - DECLARE_META_INTERFACE(SurfaceTexture); + DECLARE_META_INTERFACE(GraphicBufferProducer); enum { BUFFER_NEEDS_REALLOCATION = 0x1, @@ -45,8 +59,8 @@ public: }; // requestBuffer requests a new buffer for the given index. The server (i.e. - // the ISurfaceTexture implementation) assigns the newly created buffer to - // the given slot index, and the client is expected to mirror the + // the IGraphicBufferProducer implementation) assigns the newly created + // buffer to the given slot index, and the client is expected to mirror the // slot->buffer mapping so that it's not necessary to transfer a // GraphicBuffer for every dequeue operation. virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0; @@ -70,7 +84,7 @@ public: // 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 // immediately. - virtual status_t dequeueBuffer(int *slot, sp<Fence>& fence, + virtual status_t dequeueBuffer(int *slot, sp<Fence>* fence, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0; // queueBuffer indicates that the client has finished filling in the @@ -151,7 +165,7 @@ 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. - virtual void cancelBuffer(int slot, sp<Fence> fence) = 0; + 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 @@ -164,32 +178,32 @@ public: // The default mode is asynchronous. virtual status_t setSynchronousMode(bool enabled) = 0; - // connect attempts to connect a client API to the SurfaceTexture. This - // must be called before any other ISurfaceTexture methods are called except - // for getAllocator. + // connect attempts to connect a client API to the IGraphicBufferProducer. + // This must be called before any other IGraphicBufferProducer methods are + // called except for getAllocator. // // This method will fail if the connect was previously called on the - // SurfaceTexture and no corresponding disconnect call was made. + // 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. virtual status_t connect(int api, QueueBufferOutput* output) = 0; - // disconnect attempts to disconnect a client API from the SurfaceTexture. - // Calling this method will cause any subsequent calls to other - // ISurfaceTexture methods to fail except for getAllocator and connect. - // Successfully calling connect after this will allow the other methods to - // succeed again. + // disconnect attempts to disconnect a client API from the + // IGraphicBufferProducer. Calling this method will cause any subsequent + // calls to other IGraphicBufferProducer methods to fail except for + // getAllocator and connect. Successfully calling connect after this will + // allow the other methods to succeed again. // - // This method will fail if the the SurfaceTexture is not currently + // This method will fail if the the IGraphicBufferProducer is not currently // connected to the specified client API. virtual status_t disconnect(int api) = 0; }; // ---------------------------------------------------------------------------- -class BnSurfaceTexture : public BnInterface<ISurfaceTexture> +class BnGraphicBufferProducer : public BnInterface<IGraphicBufferProducer> { public: virtual status_t onTransact( uint32_t code, @@ -201,4 +215,4 @@ public: // ---------------------------------------------------------------------------- }; // namespace android -#endif // ANDROID_GUI_ISURFACETEXTURE_H +#endif // ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 6500ad5..9018b87 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -39,6 +39,10 @@ class DisplayInfo; class IDisplayEventConnection; class IMemoryHeap; +/* + * This class defines the Binder IPC interface for accessing various + * SurfaceFlinger features. + */ class ISurfaceComposer: public IInterface { public: DECLARE_META_INTERFACE(SurfaceComposer); @@ -86,29 +90,33 @@ public: */ virtual void bootFinished() = 0; - /* verify that an ISurfaceTexture was created by SurfaceFlinger. + /* verify that an IGraphicBufferProducer was created by SurfaceFlinger. */ virtual bool authenticateSurfaceTexture( - const sp<ISurfaceTexture>& surface) const = 0; + const sp<IGraphicBufferProducer>& surface) const = 0; - /* Capture the specified screen. requires READ_FRAME_BUFFER permission - * This function will fail if there is a secure window on screen. + /* triggers screen off and waits for it to complete + * requires ACCESS_SURFACE_FLINGER permission. */ - virtual status_t captureScreen(const sp<IBinder>& display, sp<IMemoryHeap>* heap, - uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ) = 0; - - - /* triggers screen off and waits for it to complete */ virtual void blank(const sp<IBinder>& display) = 0; - /* triggers screen on and waits for it to complete */ + /* triggers screen on and waits for it to complete + * requires ACCESS_SURFACE_FLINGER permission. + */ virtual void unblank(const sp<IBinder>& display) = 0; /* returns information about a display * intended to be used to get information about built-in displays */ virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) = 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, + bool isCpuConsumer) = 0; }; // ---------------------------------------------------------------------------- @@ -126,11 +134,11 @@ public: GET_BUILT_IN_DISPLAY, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, - CAPTURE_SCREEN, BLANK, UNBLANK, GET_DISPLAY_INFO, CONNECT_DISPLAY, + CAPTURE_SCREEN, }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index e256e33..cb9816f 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -27,11 +27,11 @@ #include <ui/PixelFormat.h> -#include <gui/ISurface.h> - namespace android { // ---------------------------------------------------------------------------- +class IGraphicBufferProducer; + class ISurfaceComposerClient : public IInterface { public: @@ -48,30 +48,23 @@ public: eProtectedByDRM = 0x00001000, eFXSurfaceNormal = 0x00000000, - eFXSurfaceBlur = 0x00010000, // deprecated, same as Dim eFXSurfaceDim = 0x00020000, - eFXSurfaceScreenshot= 0x00030000, eFXSurfaceMask = 0x000F0000, }; - struct surface_data_t { - int32_t token; - int32_t identity; - status_t readFromParcel(const Parcel& parcel); - status_t writeToParcel(Parcel* parcel) const; - }; - /* * Requires ACCESS_SURFACE_FLINGER permission */ - virtual sp<ISurface> createSurface(surface_data_t* data, + virtual status_t createSurface( const String8& name, uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags) = 0; + PixelFormat format, uint32_t flags, + sp<IBinder>* handle, + sp<IGraphicBufferProducer>* gbp) = 0; /* * Requires ACCESS_SURFACE_FLINGER permission */ - virtual status_t destroySurface(SurfaceID sid) = 0; + virtual status_t destroySurface(const sp<IBinder>& handle) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 3411f0a..c25847c 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,161 +17,235 @@ #ifndef ANDROID_GUI_SURFACE_H #define ANDROID_GUI_SURFACE_H -#include <stdint.h> -#include <sys/types.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/GLConsumer.h> +#include <gui/BufferQueue.h> -#include <utils/KeyedVector.h> -#include <utils/RefBase.h> -#include <utils/threads.h> - -#include <ui/PixelFormat.h> +#include <ui/ANativeObjectBase.h> #include <ui/Region.h> -#include <gui/SurfaceTextureClient.h> -#include <gui/ISurface.h> -#include <gui/ISurfaceComposerClient.h> +#include <utils/RefBase.h> +#include <utils/threads.h> +#include <utils/KeyedVector.h> -#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface" +struct ANativeWindow_Buffer; namespace android { -// --------------------------------------------------------------------------- - -class ISurfaceTexture; -class Surface; -class SurfaceComposerClient; - -// --------------------------------------------------------------------------- - -class SurfaceControl : public RefBase -{ -public: - static bool isValid(const sp<SurfaceControl>& surface) { - return (surface != 0) && surface->isValid(); - } - bool isValid() { - return mToken>=0 && mClient!=0; - } - static bool isSameSurface( - const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); - - uint32_t getIdentity() const { return mIdentity; } - - // release surface data from java - void clear(); - - status_t setLayerStack(int32_t layerStack); - status_t setLayer(int32_t layer); - status_t setPosition(int32_t x, int32_t y); - status_t setSize(uint32_t w, uint32_t h); - status_t hide(); - status_t show(); - status_t setFlags(uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(const Region& transparent); - status_t setAlpha(float alpha=1.0f); - status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); - status_t setCrop(const Rect& crop); - - static status_t writeSurfaceToParcel( - const sp<SurfaceControl>& control, Parcel* parcel); - - sp<Surface> getSurface() const; - -private: - // can't be copied - SurfaceControl& operator = (SurfaceControl& rhs); - SurfaceControl(const SurfaceControl& rhs); - - friend class SurfaceComposerClient; - friend class Surface; - - SurfaceControl( - const sp<SurfaceComposerClient>& client, - const sp<ISurface>& surface, - const ISurfaceComposerClient::surface_data_t& data); - - ~SurfaceControl(); - - status_t validate() const; - void destroy(); - - sp<SurfaceComposerClient> mClient; - sp<ISurface> mSurface; - SurfaceID mToken; - uint32_t mIdentity; - mutable Mutex mLock; - - mutable sp<Surface> mSurfaceData; -}; - -// --------------------------------------------------------------------------- - -class Surface : public SurfaceTextureClient +/* + * An implementation of ANativeWindow that feeds graphics buffers into a + * BufferQueue. + * + * This is typically used by programs that want to render frames through + * some means (maybe OpenGL, a software renderer, or a hardware decoder) + * and have the frames they create forwarded to SurfaceFlinger for + * compositing. For example, a video decoder could render a frame and call + * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by + * Surface. Surface then forwards the buffers through Binder IPC + * to the BufferQueue's producer interface, providing the new frame to a + * consumer such as GLConsumer. + */ +class Surface + : public ANativeObjectBase<ANativeWindow, Surface, RefBase> { public: - struct SurfaceInfo { - uint32_t w; - uint32_t h; - uint32_t s; - uint32_t usage; - PixelFormat format; - void* bits; - uint32_t reserved[2]; - }; - - explicit Surface(const sp<ISurfaceTexture>& st); - Surface (sp<BufferQueue>&) {} + /* + * creates a Surface from the given IGraphicBufferProducer (which concrete + * implementation is a BufferQueue). + * + * Surface is mainly state-less while it's disconnected, it can be + * viewed as a glorified IGraphicBufferProducer holder. It's therefore + * safe to create other Surfaces from the same IGraphicBufferProducer. + * + * However, once a Surface is connected, it'll prevent other Surfaces + * referring to the same IGraphicBufferProducer to become connected and + * therefore prevent them to be used as actual producers of buffers. + */ + Surface(const sp<IGraphicBufferProducer>& bufferProducer); - static status_t writeToParcel(const sp<Surface>& control, Parcel* parcel); + /* getIGraphicBufferProducer() returns the IGraphicBufferProducer this + * Surface was created with. Usually it's an error to use the + * IGraphicBufferProducer while the Surface is connected. + */ + sp<IGraphicBufferProducer> getIGraphicBufferProducer() const; - static sp<Surface> readFromParcel(const Parcel& data); + /* convenience function to check that the given surface is non NULL as + * well as its IGraphicBufferProducer */ static bool isValid(const sp<Surface>& surface) { - return (surface != 0) && surface->isValid(); + return surface != NULL && surface->getIGraphicBufferProducer() != NULL; } - bool isValid(); - uint32_t getIdentity() const { return mIdentity; } - sp<ISurfaceTexture> getSurfaceTexture(); - - // the lock/unlock APIs must be used from the same thread - status_t lock(SurfaceInfo* info, Region* dirty = NULL); - int lock(ANativeWindow_Buffer*, ARect*) { return 0; } - status_t unlockAndPost(); - - sp<IBinder> asBinder() const; +protected: + virtual ~Surface(); private: - // this is just to be able to write some unit tests - friend class Test; - friend class SurfaceControl; - // can't be copied - Surface& operator = (Surface& rhs); + Surface& operator = (const Surface& rhs); Surface(const Surface& rhs); - explicit Surface(const sp<SurfaceControl>& control); - Surface(const Parcel& data, const sp<IBinder>& ref); - ~Surface(); + // ANativeWindow hooks + static int hook_cancelBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_dequeueBuffer(ANativeWindow* window, + ANativeWindowBuffer** buffer, int* fenceFd); + static int hook_perform(ANativeWindow* window, int operation, ...); + static int hook_query(const ANativeWindow* window, int what, int* value); + static int hook_queueBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_setSwapInterval(ANativeWindow* window, int interval); + + static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer** buffer); + static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + + int dispatchConnect(va_list args); + int dispatchDisconnect(va_list args); + int dispatchSetBufferCount(va_list args); + int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersDimensions(va_list args); + int dispatchSetBuffersUserDimensions(va_list args); + int dispatchSetBuffersFormat(va_list args); + int dispatchSetScalingMode(va_list args); + int dispatchSetBuffersTransform(va_list args); + int 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); + +protected: + virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); + virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int perform(int operation, va_list args); + virtual int query(int what, int* value) const; + virtual int setSwapInterval(int interval); + + virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); + + virtual int connect(int api); + virtual int disconnect(int api); + virtual int setBufferCount(int bufferCount); + virtual int setBuffersDimensions(int w, int h); + virtual int setBuffersUserDimensions(int w, int h); + virtual int setBuffersFormat(int format); + virtual int setScalingMode(int mode); + virtual int setBuffersTransform(int transform); + virtual int setBuffersTimestamp(int64_t timestamp); + virtual int setCrop(Rect const* rect); + virtual int setUsage(uint32_t reqUsage); - /* - * private stuff... - */ - void init(const sp<ISurfaceTexture>& surfaceTexture); +public: + virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); + virtual int unlockAndPost(); - static void cleanCachedSurfacesLocked(); +protected: + enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS }; + enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; - virtual int query(int what, int* value) const; +private: + void freeAllBuffers(); + int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; - // constants - sp<ISurface> mSurface; - uint32_t mIdentity; + struct BufferSlot { + sp<GraphicBuffer> buffer; + Region dirtyRegion; + }; - // A cache of Surface objects that have been deserialized into this process. - static Mutex sCachedSurfacesLock; - static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces; + // mSurfaceTexture is the interface to the surface texture server. All + // operations on the surface texture client ultimately translate into + // interactions with the server using this interface. + // TODO: rename to mBufferProducer + sp<IGraphicBufferProducer> mGraphicBufferProducer; + + // mSlots stores the buffers that have been allocated for each buffer slot. + // It is initialized to null pointers, and gets filled in with the result of + // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + BufferSlot mSlots[NUM_BUFFER_SLOTS]; + + // mReqWidth is the buffer width that will be requested at the next dequeue + // operation. It is initialized to 1. + uint32_t mReqWidth; + + // mReqHeight is the buffer height that will be requested at the next + // dequeue operation. It is initialized to 1. + uint32_t mReqHeight; + + // mReqFormat is the buffer pixel format that will be requested at the next + // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. + uint32_t mReqFormat; + + // mReqUsage is the set of buffer usage flags that will be requested + // at the next deuque operation. It is initialized to 0. + uint32_t mReqUsage; + + // mTimestamp is the timestamp that will be used for the next buffer queue + // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that + // a timestamp is auto-generated when queueBuffer is called. + int64_t mTimestamp; + + // mCrop is the crop rectangle that will be used for the next buffer + // that gets queued. It is set by calling setCrop. + Rect mCrop; + + // mScalingMode is the scaling mode that will be used for the next + // buffers that get queued. It is set by calling setScalingMode. + int mScalingMode; + + // mTransform is the transform identifier that will be used for the next + // buffer that gets queued. It is set by calling setTransform. + uint32_t mTransform; + + // mDefaultWidth is default width of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultWidth; + + // mDefaultHeight is default height of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultHeight; + + // mUserWidth, if non-zero, is an application-specified override + // of mDefaultWidth. This is lower priority than the width set by + // native_window_set_buffers_dimensions. + uint32_t mUserWidth; + + // mUserHeight, if non-zero, is an application-specified override + // of mDefaultHeight. This is lower priority than the height set + // by native_window_set_buffers_dimensions. + uint32_t mUserHeight; + + // mTransformHint is the transform probably applied to buffers of this + // window. this is only a hint, actual transform may differ. + uint32_t mTransformHint; + + // mConsumerRunningBehind whether the consumer is running more than + // one buffer behind the producer. + mutable bool mConsumerRunningBehind; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of Surface objects. It must be locked whenever the + // member variables are accessed. + mutable Mutex mMutex; + + // must be used from the lock/unlock thread + sp<GraphicBuffer> mLockedBuffer; + sp<GraphicBuffer> mPostedBuffer; + bool mConnectedToCpu; + + // must be accessed from lock/unlock thread only + Region mDirtyRegion; }; }; // namespace android -#endif // ANDROID_GUI_SURFACE_H +#endif // ANDROID_GUI_SURFACE_H diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index ae5d69a..6bf5b47 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -21,6 +21,7 @@ #include <sys/types.h> #include <binder/IBinder.h> +#include <binder/IMemory.h> #include <utils/RefBase.h> #include <utils/Singleton.h> @@ -29,7 +30,8 @@ #include <ui/PixelFormat.h> -#include <gui/Surface.h> +#include <gui/CpuConsumer.h> +#include <gui/SurfaceControl.h> namespace android { @@ -37,9 +39,8 @@ namespace android { class DisplayInfo; class Composer; -class IMemoryHeap; class ISurfaceComposerClient; -class ISurfaceTexture; +class IGraphicBufferProducer; class Region; // --------------------------------------------------------------------------- @@ -108,21 +109,21 @@ public: //! Flag the currently open transaction as an animation transaction. static void setAnimationTransaction(); - status_t hide(SurfaceID id); - status_t show(SurfaceID id); - status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask); - status_t setTransparentRegionHint(SurfaceID id, const Region& transparent); - status_t setLayer(SurfaceID id, int32_t layer); - status_t setAlpha(SurfaceID id, float alpha=1.0f); - status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); - status_t setPosition(SurfaceID id, float x, float y); - status_t setSize(SurfaceID id, uint32_t w, uint32_t h); - status_t setCrop(SurfaceID id, const Rect& crop); - status_t setLayerStack(SurfaceID id, uint32_t layerStack); - status_t destroySurface(SurfaceID sid); + status_t hide(const sp<IBinder>& id); + status_t show(const sp<IBinder>& id); + status_t setFlags(const sp<IBinder>& id, uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent); + status_t setLayer(const sp<IBinder>& id, int32_t layer); + status_t setAlpha(const sp<IBinder>& id, float alpha=1.0f); + status_t setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy); + status_t setPosition(const sp<IBinder>& id, float x, float y); + status_t setSize(const sp<IBinder>& id, uint32_t w, uint32_t h); + status_t setCrop(const sp<IBinder>& id, const Rect& crop); + status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); + status_t destroySurface(const sp<IBinder>& id); static void setDisplaySurface(const sp<IBinder>& token, - const sp<ISurfaceTexture>& surface); + const sp<IGraphicBufferProducer>& bufferProducer); static void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack); @@ -155,12 +156,21 @@ private: class ScreenshotClient { - sp<IMemoryHeap> mHeap; - uint32_t mWidth; - uint32_t mHeight; - PixelFormat mFormat; +public: + static status_t capture( + const sp<IBinder>& display, + const sp<IGraphicBufferProducer>& producer, + uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ); + +private: + mutable sp<CpuConsumer> mCpuConsumer; + CpuConsumer::LockedBuffer mBuffer; + bool mHaveBuffer; + public: ScreenshotClient(); + ~ScreenshotClient(); // frees the previous screenshot and capture a new one status_t update(const sp<IBinder>& display); @@ -170,6 +180,8 @@ public: uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ); + sp<CpuConsumer> getCpuConsumer() const; + // release memory occupied by the screenshot void release(); diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h new file mode 100644 index 0000000..f27754c --- /dev/null +++ b/include/gui/SurfaceControl.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_CONTROL_H +#define ANDROID_GUI_SURFACE_CONTROL_H + +#include <stdint.h> +#include <sys/types.h> + +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/threads.h> + +#include <ui/PixelFormat.h> +#include <ui/Region.h> + +#include <gui/ISurfaceComposerClient.h> + +namespace android { + +// --------------------------------------------------------------------------- + +class IGraphicBufferProducer; +class Surface; +class SurfaceComposerClient; + +// --------------------------------------------------------------------------- + +class SurfaceControl : public RefBase +{ +public: + static bool isValid(const sp<SurfaceControl>& surface) { + return (surface != 0) && surface->isValid(); + } + + bool isValid() { + return mHandle!=0 && mClient!=0; + } + + static bool isSameSurface( + const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); + + // release surface data from java + void clear(); + + status_t setLayerStack(int32_t layerStack); + status_t setLayer(int32_t layer); + status_t setPosition(float x, float y); + status_t setSize(uint32_t w, uint32_t h); + status_t hide(); + status_t show(); + status_t setFlags(uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const Region& transparent); + status_t setAlpha(float alpha=1.0f); + status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); + status_t setCrop(const Rect& crop); + + static status_t writeSurfaceToParcel( + const sp<SurfaceControl>& control, Parcel* parcel); + + sp<Surface> getSurface() const; + +private: + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class SurfaceComposerClient; + friend class Surface; + + SurfaceControl( + const sp<SurfaceComposerClient>& client, + const sp<IBinder>& handle, + const sp<IGraphicBufferProducer>& gbp); + + ~SurfaceControl(); + + status_t validate() const; + void destroy(); + + sp<SurfaceComposerClient> mClient; + sp<IBinder> mHandle; + sp<IGraphicBufferProducer> mGraphicBufferProducer; + mutable Mutex mLock; + mutable sp<Surface> mSurfaceData; +}; + +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_CONTROL_H diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h deleted file mode 100644 index 7c519ae..0000000 --- a/include/gui/SurfaceTexture.h +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_GUI_SURFACETEXTURE_H -#define ANDROID_GUI_SURFACETEXTURE_H - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> - -#include <gui/ISurfaceTexture.h> -#include <gui/BufferQueue.h> -#include <gui/ConsumerBase.h> - -#include <ui/GraphicBuffer.h> - -#include <utils/String8.h> -#include <utils/Vector.h> -#include <utils/threads.h> - -#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" - -namespace android { -// ---------------------------------------------------------------------------- - - -class String8; - -class SurfaceTexture : public ConsumerBase { -public: - typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; - - // SurfaceTexture constructs a new SurfaceTexture 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 SurfaceTexture 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. - // - // A SurfaceTexture may be detached from one OpenGL ES context and then - // attached to a different context using the detachFromContext and - // attachToContext methods, respectively. The intention of these methods is - // purely to allow a SurfaceTexture 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. - SurfaceTexture(GLuint tex, bool allowSynchronousMode = true, - GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true, - const sp<BufferQueue> &bufferQueue = 0); - - // updateTexImage sets the image contents of the target texture to that of - // the most recently queued buffer. - // - // This call may only be made while the OpenGL ES context to which the - // target texture belongs is bound to the calling thread. - // - // After calling this method the doGLFenceWait method must be called - // before issuing OpenGL ES commands that access the texture contents. - status_t updateTexImage(); - - // setReleaseFence stores a fence file descriptor that will signal when the - // current buffer is no longer being read. This fence will be returned to - // the producer when the current buffer is released by updateTexImage(). - // Multiple fences can be set for a given buffer; they will be merged into - // a single union fence. The SurfaceTexture will close the file descriptor - // when finished with it. - void setReleaseFence(int fenceFd); - - // setDefaultMaxBufferCount sets the default limit on the maximum number - // of buffers that will be allocated at one time. The image producer may - // override the limit. - status_t setDefaultMaxBufferCount(int bufferCount); - - // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix - // associated with the texture image set by the most recent call to - // updateTexImage. - // - // This transform matrix maps 2D homogeneous texture coordinates of the form - // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture - // coordinate that should be used to sample that location from the texture. - // Sampling the texture outside of the range of this transform is undefined. - // - // This transform is necessary to compensate for transforms that the stream - // content producer may implicitly apply to the content. By forcing users of - // a SurfaceTexture to apply this transform we avoid performing an extra - // copy of the data that would be needed to hide the transform from the - // user. - // - // The matrix is stored in column-major order so that it may be passed - // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv - // functions. - void getTransformMatrix(float mtx[16]); - - // getTimestamp retrieves the timestamp associated with the texture image - // set by the most recent call to updateTexImage. - // - // The timestamp is in nanoseconds, and is monotonically increasing. Its - // other semantics (zero point, etc) are source-dependent and should be - // documented by the source. - int64_t getTimestamp(); - - // setDefaultBufferSize is used to set the size of buffers returned by - // requestBuffers when a with and height of zero is requested. - // A call to setDefaultBufferSize() may trigger requestBuffers() to - // be called from the client. - // The width and height parameters must be no greater than the minimum of - // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). - // An error due to invalid dimensions might not be reported until - // updateTexImage() is called. - status_t setDefaultBufferSize(uint32_t width, uint32_t height); - - // setFilteringEnabled sets whether the transform matrix should be computed - // for use with bilinear filtering. - void setFilteringEnabled(bool enabled); - - // getCurrentBuffer returns the buffer associated with the current image. - sp<GraphicBuffer> getCurrentBuffer() const; - - // getCurrentTextureTarget returns the texture target of the current - // texture as returned by updateTexImage(). - GLenum getCurrentTextureTarget() const; - - // getCurrentCrop returns the cropping rectangle of the current buffer. - Rect getCurrentCrop() const; - - // getCurrentTransform returns the transform of the current buffer. - uint32_t getCurrentTransform() const; - - // getCurrentScalingMode returns the scaling mode of the current buffer. - uint32_t getCurrentScalingMode() const; - - // getCurrentFence returns the fence indicating when the current buffer is - // ready to be read from. - sp<Fence> getCurrentFence() const; - - // doGLFenceWait inserts a wait command into the OpenGL ES command stream - // to ensure that it is safe for future OpenGL ES commands to access the - // current texture buffer. This must be called each time updateTexImage - // is called before issuing OpenGL ES commands that access the texture. - status_t doGLFenceWait() const; - - // isSynchronousMode returns whether the SurfaceTexture is currently in - // synchronous mode. - bool isSynchronousMode() const; - - // set the name of the SurfaceTexture that will be used to identify it in - // log messages. - void setName(const String8& name); - - // These functions call the corresponding BufferQueue implementation - // so the refactoring can proceed smoothly - status_t setDefaultBufferFormat(uint32_t defaultFormat); - status_t setConsumerUsageBits(uint32_t usage); - status_t setTransformHint(uint32_t hint); - virtual status_t setSynchronousMode(bool enabled); - - // getBufferQueue returns the BufferQueue object to which this - // SurfaceTexture is connected. - sp<BufferQueue> getBufferQueue() const { - return mBufferQueue; - } - - // detachFromContext detaches the SurfaceTexture from the calling thread's - // current OpenGL ES context. This context must be the same as the context - // that was current for previous calls to updateTexImage. - // - // Detaching a SurfaceTexture from an OpenGL ES context will result in the - // deletion of the OpenGL ES texture object into which the images were being - // streamed. After a SurfaceTexture has been detached from the OpenGL ES - // context calls to updateTexImage will fail returning INVALID_OPERATION - // until the SurfaceTexture is attached to a new OpenGL ES context using the - // attachToContext method. - status_t detachFromContext(); - - // attachToContext attaches a SurfaceTexture that is currently in the - // 'detached' state to the current OpenGL ES context. A SurfaceTexture is - // in the 'detached' state iff detachFromContext has successfully been - // called and no calls to attachToContext have succeeded since the last - // detachFromContext call. Calls to attachToContext made on a - // SurfaceTexture that is not in the 'detached' state will result in an - // INVALID_OPERATION error. - // - // The tex argument specifies the OpenGL ES texture object name in the - // new context into which the image contents will be streamed. A successful - // call to attachToContext will result in this texture object being bound to - // the texture target and populated with the image contents that were - // current at the time of the last call to detachFromContext. - status_t attachToContext(GLuint tex); - -protected: - - // abandonLocked overrides the ConsumerBase method to clear - // mCurrentTextureBuf in addition to the ConsumerBase behavior. - virtual void abandonLocked(); - - // dumpLocked overrides the ConsumerBase method to dump SurfaceTexture- - // specific info in addition to the ConsumerBase behavior. - virtual void dumpLocked(String8& result, const char* prefix, char* buffer, - size_t size) const; - - // acquireBufferLocked overrides the ConsumerBase method to update the - // mEglSlots array in addition to the ConsumerBase behavior. - virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item); - - // releaseBufferLocked overrides the ConsumerBase method to update the - // mEglSlots array in addition to the ConsumerBase. - virtual status_t releaseBufferLocked(int buf, EGLDisplay display, - EGLSyncKHR eglFence); - - static bool isExternalFormat(uint32_t format); - -private: - // this version of updateTexImage() takes a functor used to reject or not - // the newly acquired buffer. - // this API is TEMPORARY and intended to be used by SurfaceFlinger only, - // which is why class Layer is made a friend of SurfaceTexture below. - class BufferRejecter { - friend class SurfaceTexture; - virtual bool reject(const sp<GraphicBuffer>& buf, - const BufferQueue::BufferItem& item) = 0; - protected: - virtual ~BufferRejecter() { } - }; - friend class Layer; - status_t updateTexImage(BufferRejecter* rejecter, bool skipSync); - - // createImage creates a new EGLImage from a GraphicBuffer. - EGLImageKHR createImage(EGLDisplay dpy, - const sp<GraphicBuffer>& graphicBuffer); - - // freeBufferLocked frees up the given buffer slot. If the slot has been - // initialized this will release the reference to the GraphicBuffer in that - // slot and destroy the EGLImage in that slot. Otherwise it has no effect. - // - // This method must be called with mMutex locked. - virtual void freeBufferLocked(int slotIndex); - - // computeCurrentTransformMatrixLocked computes the transform matrix for the - // current texture. It uses mCurrentTransform and the current GraphicBuffer - // to compute this matrix and stores it in mCurrentTransformMatrix. - // mCurrentTextureBuf must not be NULL. - void computeCurrentTransformMatrixLocked(); - - // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command - // stream to ensure that it is safe for future OpenGL ES commands to - // access the current texture buffer. This must be called each time - // updateTexImage is called before issuing OpenGL ES commands that access - // the texture. - status_t doGLFenceWaitLocked() const; - - // syncForReleaseLocked performs the synchronization needed to release the - // current slot from an OpenGL ES context. If needed it will set the - // current slot's fence to guard against a producer accessing the buffer - // before the outstanding accesses have completed. - status_t syncForReleaseLocked(EGLDisplay dpy); - - // The default consumer usage flags that SurfaceTexture always sets on its - // BufferQueue instance; these will be OR:d with any additional flags passed - // from the SurfaceTexture user. In particular, SurfaceTexture will always - // 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 - // 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; - - // mCurrentCrop is the crop rectangle that applies to the current texture. - // It gets set each time updateTexImage is called. - Rect mCurrentCrop; - - // mCurrentTransform is the transform identifier for the current texture. It - // gets set each time updateTexImage is called. - uint32_t mCurrentTransform; - - // mCurrentScalingMode is the scaling mode for the current texture. It gets - // set to each time updateTexImage is called. - uint32_t mCurrentScalingMode; - - // mCurrentFence is the fence received from BufferQueue in updateTexImage. - sp<Fence> mCurrentFence; - - // mCurrentTransformMatrix is the transform matrix for the current texture. - // It gets computed by computeTransformMatrix each time updateTexImage is - // called. - float mCurrentTransformMatrix[16]; - - // mCurrentTimestamp is the timestamp for the current texture. It - // gets set each time updateTexImage is called. - int64_t mCurrentTimestamp; - - uint32_t mDefaultWidth, mDefaultHeight; - - // mFilteringEnabled indicates whether the transform matrix is computed for - // use with bilinear filtering. It defaults to true and is changed by - // setFilteringEnabled(). - bool mFilteringEnabled; - - // mTexName is the name of the OpenGL texture to which streamed images will - // be bound when updateTexImage is called. It is set at construction time - // and can be changed with a call to attachToContext. - GLuint mTexName; - - // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync - // extension should be used to prevent buffers from being dequeued before - // it's safe for them to be written. It gets set at construction time and - // never changes. - const bool mUseFenceSync; - - // mTexTarget is the GL texture target with which the GL texture object is - // associated. It is set in the constructor and never changed. It is - // almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android - // Browser. In that case it is set to GL_TEXTURE_2D to allow - // glCopyTexSubImage to read from the texture. This is a hack to work - // around a GL driver limitation on the number of FBO attachments, which the - // browser's tile cache exceeds. - const GLenum mTexTarget; - - // EGLSlot contains the information and object references that - // SurfaceTexture maintains about a BufferQueue buffer slot. - struct EGLSlot { - EGLSlot() - : mEglImage(EGL_NO_IMAGE_KHR), - mEglFence(EGL_NO_SYNC_KHR) { - } - - // mEglImage is the EGLImage created from mGraphicBuffer. - EGLImageKHR mEglImage; - - // mFence is the EGL sync object that must signal before the buffer - // associated with this buffer slot may be dequeued. It is initialized - // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based - // on a compile-time option) set to a new sync object in updateTexImage. - EGLSyncKHR mEglFence; - }; - - // mEglDisplay is the EGLDisplay with which this SurfaceTexture is currently - // associated. It is intialized to EGL_NO_DISPLAY and gets set to the - // current display when updateTexImage is called for the first time and when - // attachToContext is called. - EGLDisplay mEglDisplay; - - // mEglContext is the OpenGL ES context with which this SurfaceTexture is - // currently associated. It is initialized to EGL_NO_CONTEXT and gets set - // to the current GL context when updateTexImage is called for the first - // time and when attachToContext is called. - EGLContext mEglContext; - - // mEGLSlots stores the buffers that have been allocated by the BufferQueue - // for each buffer slot. It is initialized to null pointers, and gets - // filled in with the result of BufferQueue::acquire when the - // client dequeues a buffer from a - // slot that has not yet been used. The buffer allocated to a slot will also - // be replaced if the requested buffer usage or geometry differs from that - // of the buffer allocated to a slot. - EGLSlot mEglSlots[BufferQueue::NUM_BUFFER_SLOTS]; - - // mCurrentTexture is the buffer slot index of the buffer that is currently - // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT, - // indicating that no buffer slot is currently bound to the texture. Note, - // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean - // that no buffer is bound to the texture. A call to setBufferCount will - // reset mCurrentTexture to INVALID_BUFFER_SLOT. - int mCurrentTexture; - - // mAttached indicates whether the ConsumerBase is currently attached to - // an OpenGL ES context. For legacy reasons, this is initialized to true, - // indicating that the ConsumerBase is considered to be attached to - // whatever context is current at the time of the first updateTexImage call. - // It is set to false by detachFromContext, and then set to true again by - // attachToContext. - bool mAttached; -}; - -// ---------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_GUI_SURFACETEXTURE_H diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h deleted file mode 100644 index 50fd1ba..0000000 --- a/include/gui/SurfaceTextureClient.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_GUI_SURFACETEXTURECLIENT_H -#define ANDROID_GUI_SURFACETEXTURECLIENT_H - -#include <gui/ISurfaceTexture.h> -#include <gui/SurfaceTexture.h> -#include <gui/BufferQueue.h> - -#include <ui/ANativeObjectBase.h> -#include <ui/Region.h> - -#include <utils/RefBase.h> -#include <utils/threads.h> -#include <utils/KeyedVector.h> - -struct ANativeWindow_Buffer; - -namespace android { - -class Surface; - -class SurfaceTextureClient - : public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase> -{ -public: - - SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture); - - // SurfaceTextureClient is overloaded to assist in refactoring ST and BQ. - // SurfaceTexture is no longer an ISurfaceTexture, so client code - // calling the original constructor will fail. Thus this convenience method - // passes in the surfaceTexture's bufferQueue to the init method. - SurfaceTextureClient(const sp<SurfaceTexture>& surfaceTexture); - - sp<ISurfaceTexture> getISurfaceTexture() const; - -protected: - SurfaceTextureClient(); - virtual ~SurfaceTextureClient(); - void setISurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture); - -private: - // can't be copied - SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs); - SurfaceTextureClient(const SurfaceTextureClient& rhs); - void init(); - - // ANativeWindow hooks - static int hook_cancelBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd); - static int hook_dequeueBuffer(ANativeWindow* window, - ANativeWindowBuffer** buffer, int* fenceFd); - static int hook_perform(ANativeWindow* window, int operation, ...); - static int hook_query(const ANativeWindow* window, int what, int* value); - static int hook_queueBuffer(ANativeWindow* window, - ANativeWindowBuffer* buffer, int fenceFd); - static int hook_setSwapInterval(ANativeWindow* window, int interval); - - static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer); - static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer** buffer); - static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer); - static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, - ANativeWindowBuffer* buffer); - - int dispatchConnect(va_list args); - int dispatchDisconnect(va_list args); - int dispatchSetBufferCount(va_list args); - int dispatchSetBuffersGeometry(va_list args); - int dispatchSetBuffersDimensions(va_list args); - int dispatchSetBuffersUserDimensions(va_list args); - int dispatchSetBuffersFormat(va_list args); - int dispatchSetScalingMode(va_list args); - int dispatchSetBuffersTransform(va_list args); - int 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); - -protected: - virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); - virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); - virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); - virtual int perform(int operation, va_list args); - virtual int query(int what, int* value) const; - virtual int setSwapInterval(int interval); - - virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); - - virtual int connect(int api); - virtual int disconnect(int api); - virtual int setBufferCount(int bufferCount); - virtual int setBuffersDimensions(int w, int h); - virtual int setBuffersUserDimensions(int w, int h); - virtual int setBuffersFormat(int format); - virtual int setScalingMode(int mode); - virtual int setBuffersTransform(int transform); - virtual int setBuffersTimestamp(int64_t timestamp); - virtual int setCrop(Rect const* rect); - virtual int setUsage(uint32_t reqUsage); - virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); - virtual int unlockAndPost(); - - enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS }; - enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; - -private: - void freeAllBuffers(); - int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; - - struct BufferSlot { - sp<GraphicBuffer> buffer; - Region dirtyRegion; - }; - - // mSurfaceTexture is the interface to the surface texture server. All - // operations on the surface texture client ultimately translate into - // interactions with the server using this interface. - sp<ISurfaceTexture> mSurfaceTexture; - - // mSlots stores the buffers that have been allocated for each buffer slot. - // It is initialized to null pointers, and gets filled in with the result of - // ISurfaceTexture::requestBuffer when the client dequeues a buffer from a - // slot that has not yet been used. The buffer allocated to a slot will also - // be replaced if the requested buffer usage or geometry differs from that - // of the buffer allocated to a slot. - BufferSlot mSlots[NUM_BUFFER_SLOTS]; - - // mReqWidth is the buffer width that will be requested at the next dequeue - // operation. It is initialized to 1. - uint32_t mReqWidth; - - // mReqHeight is the buffer height that will be requested at the next - // dequeue operation. It is initialized to 1. - uint32_t mReqHeight; - - // mReqFormat is the buffer pixel format that will be requested at the next - // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. - uint32_t mReqFormat; - - // mReqUsage is the set of buffer usage flags that will be requested - // at the next deuque operation. It is initialized to 0. - uint32_t mReqUsage; - - // mTimestamp is the timestamp that will be used for the next buffer queue - // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that - // a timestamp is auto-generated when queueBuffer is called. - int64_t mTimestamp; - - // mCrop is the crop rectangle that will be used for the next buffer - // that gets queued. It is set by calling setCrop. - Rect mCrop; - - // mScalingMode is the scaling mode that will be used for the next - // buffers that get queued. It is set by calling setScalingMode. - int mScalingMode; - - // mTransform is the transform identifier that will be used for the next - // buffer that gets queued. It is set by calling setTransform. - uint32_t mTransform; - - // mDefaultWidth is default width of the buffers, regardless of the - // native_window_set_buffers_dimensions call. - uint32_t mDefaultWidth; - - // mDefaultHeight is default height of the buffers, regardless of the - // native_window_set_buffers_dimensions call. - uint32_t mDefaultHeight; - - // mUserWidth, if non-zero, is an application-specified override - // of mDefaultWidth. This is lower priority than the width set by - // native_window_set_buffers_dimensions. - uint32_t mUserWidth; - - // mUserHeight, if non-zero, is an application-specified override - // of mDefaultHeight. This is lower priority than the height set - // by native_window_set_buffers_dimensions. - uint32_t mUserHeight; - - // mTransformHint is the transform probably applied to buffers of this - // window. this is only a hint, actual transform may differ. - uint32_t mTransformHint; - - // mConsumerRunningBehind whether the consumer is running more than - // one buffer behind the producer. - mutable bool mConsumerRunningBehind; - - // mMutex is the mutex used to prevent concurrent access to the member - // variables of SurfaceTexture objects. It must be locked whenever the - // member variables are accessed. - mutable Mutex mMutex; - - // must be used from the lock/unlock thread - sp<GraphicBuffer> mLockedBuffer; - sp<GraphicBuffer> mPostedBuffer; - bool mConnectedToCpu; - - // must be accessed from lock/unlock thread only - Region mDirtyRegion; -}; - -}; // namespace android - -#endif // ANDROID_GUI_SURFACETEXTURECLIENT_H diff --git a/include/input/KeycodeLabels.h b/include/input/KeycodeLabels.h new file mode 100644 index 0000000..1e91ea8 --- /dev/null +++ b/include/input/KeycodeLabels.h @@ -0,0 +1,6 @@ +#ifndef _LIBINPUT_KEYCODE_LABELS_H +#define _LIBINPUT_KEYCODE_LABELS_H + +#include <androidfw/KeycodeLabels.h> + +#endif // _LIBINPUT_KEYCODE_LABELS_H diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h new file mode 100644 index 0000000..fbf93bc --- /dev/null +++ b/include/media/drm/DrmAPI.h @@ -0,0 +1,330 @@ +/* + * 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 DRM_API_H_ +#define DRM_API_H_ + +#include <utils/List.h> +#include <utils/String8.h> +#include <utils/Vector.h> +#include <utils/KeyedVector.h> +#include <utils/RefBase.h> +#include <utils/Mutex.h> +#include <media/stagefright/foundation/ABase.h> + +// Loadable DrmEngine shared libraries should define the entry points +// createDrmFactory and createCryptoFactory as shown below: +// +// extern "C" { +// extern android::DrmFactory *createDrmFactory(); +// extern android::CryptoFactory *createCryptoFactory(); +// } + +namespace android { + + class DrmPlugin; + class DrmPluginListener; + + // DRMs are implemented in DrmEngine plugins, which are dynamically + // loadable shared libraries that implement the entry points + // createDrmFactory and createCryptoFactory. createDrmFactory + // constructs and returns an instance of a DrmFactory object. Similarly, + // createCryptoFactory creates an instance of a CryptoFactory object. + // When a MediaCrypto or MediaDrm object needs to be constructed, all + // available DrmEngines present in the plugins directory on the device + // are scanned for a matching DrmEngine that can support the crypto + // scheme. When a match is found, the DrmEngine's createCryptoPlugin and + // createDrmPlugin methods are used to create CryptoPlugin or + // DrmPlugin instances to support that DRM scheme. + + class DrmFactory { + public: + DrmFactory() {} + virtual ~DrmFactory() {} + + // DrmFactory::isCryptoSchemeSupported can be called to determine + // if the plugin factory is able to construct plugins that support a + // given crypto scheme, which is specified by a UUID. + virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0; + + // Construct a DrmPlugin for the crypto scheme specified by UUID. + virtual status_t createDrmPlugin( + const uint8_t uuid[16], DrmPlugin **plugin) = 0; + + private: + DrmFactory(const DrmFactory &); + DrmFactory &operator=(const DrmFactory &); + }; + + class DrmPlugin { + public: + enum EventType { + kDrmPluginEventProvisionRequired = 1, + kDrmPluginEventKeyNeeded, + kDrmPluginEventKeyExpired, + kDrmPluginEventVendorDefined + }; + + // Drm keys can be for offline content or for online streaming. + // Offline keys are persisted on the device and may be used when the device + // is disconnected from the network. The Release type is used to request + // that offline keys be no longer restricted to offline use. + enum KeyType { + kKeyType_Offline, + kKeyType_Streaming, + kKeyType_Release + }; + + DrmPlugin() {} + virtual ~DrmPlugin() {} + + // Open a new session with the DrmPlugin object. A session ID is returned + // in the sessionId parameter. + virtual status_t openSession(Vector<uint8_t> &sessionId) = 0; + + // Close a session on the DrmPlugin object. + virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0; + + // A key request/response exchange occurs between the app and a License + // Server to obtain the keys required to decrypt the content. getKeyRequest() + // is used to obtain an opaque key request blob that is delivered to the + // license server. + // + // The scope parameter may be a sessionId or a keySetId, depending on the + // specified keyType. When the keyType is kKeyType_Offline or + // kKeyType_Streaming, scope should be set to the sessionId the keys will be + // provided to. When the keyType is kKeyType_Release, scope should be set to + // the keySetId of the keys being released. Releasing keys from a device + // invalidates them for all sessions. + // + // The init data passed to getKeyRequest is container-specific and its + // meaning is interpreted based on the mime type provided in the mimeType + // parameter to getKeyRequest. It could contain, for example, the content + // ID, key ID or other data obtained from the content metadata that is required + // in generating the key request. Init may be null when keyType is + // kKeyType_Release. + // + // mimeType identifies the mime type of the content + // + // keyType specifies if the keys are to be used for streaming or offline content + // + // optionalParameters are included in the key request message to allow a + // client application to provide additional message parameters to the server. + // + // If successful, the opaque key request blob is returned to the caller. + virtual status_t + getKeyRequest(Vector<uint8_t> const &scope, + Vector<uint8_t> const &initData, + String8 const &mimeType, KeyType keyType, + KeyedVector<String8, String8> const &optionalParameters, + Vector<uint8_t> &request, String8 &defaultUrl) = 0; + + // + // After a key response is received by the app, it is provided to the + // Drm plugin using provideKeyResponse. + // + // scope may be a sessionId or a keySetId depending on the type of the + // response. Scope should be set to the sessionId when the response is + // for either streaming or offline key requests. Scope should be set to the + // keySetId when the response is for a release request. + // + // When the response is for an offline key request, a keySetId is returned + // in the keySetId vector parameter that can be used to later restore the + // keys to a new session with the method restoreKeys. When the response is + // for a streaming or release request, no keySetId is returned. + // + virtual status_t provideKeyResponse(Vector<uint8_t> const &scope, + Vector<uint8_t> const &response, + Vector<uint8_t> &keySetId) = 0; + + // Remove the current keys from a session + virtual status_t removeKeys(Vector<uint8_t> const &sessionId) = 0; + + // Restore persisted offline keys into a new session. keySetId identifies + // the keys to load, obtained from a prior call to provideKeyResponse(). + virtual status_t restoreKeys(Vector<uint8_t> const &sessionId, + Vector<uint8_t> const &keySetId) = 0; + + // Request an informative description of the license for the session. The status + // is in the form of {name, value} pairs. Since DRM license policies vary by + // vendor, the specific status field names are determined by each DRM vendor. + // Refer to your DRM provider documentation for definitions of the field names + // for a particular DrmEngine. + virtual status_t + queryKeyStatus(Vector<uint8_t> const &sessionId, + KeyedVector<String8, String8> &infoMap) const = 0; + + // A provision request/response exchange occurs between the app and a + // provisioning server to retrieve a device certificate. getProvisionRequest + // is used to obtain an opaque key request blob that is delivered to the + // provisioning server. + // + // If successful, the opaque provision request blob is returned to the caller. + virtual status_t getProvisionRequest(Vector<uint8_t> &request, + String8 &defaultUrl) = 0; + + // After a provision response is received by the app, it is provided to the + // Drm plugin using provideProvisionResponse. + virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) = 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 + // on a device can be interrupted due to reboot, power failure, etc. a means + // of persisting the lifetime information on the device is needed. + // + // A signed version of the sessionID is written to persistent storage on the + // device when each MediaCrypto object is created. The sessionID is signed by + // the device private key to prevent tampering. + // + // In the normal case, playback will be completed, the session destroyed and + // the Secure Stops will be queried. The App queries secure stops and forwards + // the secure stop message to the server which verifies the signature and + // notifies the server side database that the session destruction has been + // confirmed. The persisted record on the client is only removed after positive + // confirmation that the server received the message using releaseSecureStops(). + virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; + virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0; + + // Read a property value given the device property string. There are a few forms + // of property access methods, depending on the data type returned. + // Since DRM plugin properties may vary, additional field names may be defined + // by each DRM vendor. Refer to your DRM provider documentation for definitions + // of its additional field names. + // + // Standard values are: + // "vendor" [string] identifies the maker of the plugin + // "version" [string] identifies the version of the plugin + // "description" [string] describes the plugin + // 'deviceUniqueId' [byte array] The device unique identifier is established + // during device provisioning and provides a means of uniquely identifying + // each device. + virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0; + virtual status_t getPropertyByteArray(String8 const &name, + Vector<uint8_t> &value ) const = 0; + + // Write a property value given the device property string. There are a few forms + // of property setting methods, depending on the data type. + // Since DRM plugin properties may vary, additional field names may be defined + // by each DRM vendor. Refer to your DRM provider documentation for definitions + // of its field names. + virtual status_t setPropertyString(String8 const &name, + String8 const &value ) = 0; + virtual status_t setPropertyByteArray(String8 const &name, + Vector<uint8_t> const &value ) = 0; + + // The following methods implement operations on a CryptoSession to support + // encrypt, decrypt, sign verify operations on operator-provided + // session keys. + + // + // The algorithm string conforms to JCA Standard Names for Cipher + // Transforms and is case insensitive. For example "AES/CBC/PKCS5Padding". + // + // Return OK if the algorithm is supported, otherwise return BAD_VALUE + // + virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId, + String8 const &algorithm) = 0; + + // + // The algorithm string conforms to JCA Standard Names for Mac + // Algorithms and is case insensitive. For example "HmacSHA256". + // + // Return OK if the algorithm is supported, otherwise return BAD_VALUE + // + virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId, + String8 const &algorithm) = 0; + + // Encrypt the provided input buffer with the cipher algorithm + // specified by setCipherAlgorithm and the key selected by keyId, + // and return the encrypted data. + virtual status_t encrypt(Vector<uint8_t> const &sessionId, + Vector<uint8_t> const &keyId, + Vector<uint8_t> const &input, + Vector<uint8_t> const &iv, + Vector<uint8_t> &output) = 0; + + // Decrypt the provided input buffer with the cipher algorithm + // specified by setCipherAlgorithm and the key selected by keyId, + // and return the decrypted data. + virtual status_t decrypt(Vector<uint8_t> const &sessionId, + Vector<uint8_t> const &keyId, + Vector<uint8_t> const &input, + Vector<uint8_t> const &iv, + Vector<uint8_t> &output) = 0; + + // Compute a signature on the provided message using the mac algorithm + // specified by setMacAlgorithm and the key selected by keyId, + // and return the signature. + virtual status_t sign(Vector<uint8_t> const &sessionId, + Vector<uint8_t> const &keyId, + Vector<uint8_t> const &message, + Vector<uint8_t> &signature) = 0; + + // Compute a signature on the provided message using the mac algorithm + // specified by setMacAlgorithm and the key selected by keyId, + // and compare with the expected result. Set result to true or + // false depending on the outcome. + virtual status_t verify(Vector<uint8_t> const &sessionId, + Vector<uint8_t> const &keyId, + Vector<uint8_t> const &message, + Vector<uint8_t> const &signature, + bool &match) = 0; + + + status_t setListener(const sp<DrmPluginListener>& listener) { + Mutex::Autolock lock(mEventLock); + mListener = listener; + return OK; + } + + protected: + // Plugins call sendEvent to deliver events to the java app + void sendEvent(EventType eventType, int extra, + Vector<uint8_t> const *sessionId, + Vector<uint8_t> const *data); + + private: + Mutex mEventLock; + sp<DrmPluginListener> mListener; + + DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin); + }; + + class DrmPluginListener: virtual public RefBase + { + public: + virtual void sendEvent(DrmPlugin::EventType eventType, int extra, + Vector<uint8_t> const *sesionId, + Vector<uint8_t> const *data) = 0; + }; + + inline void DrmPlugin::sendEvent(EventType eventType, int extra, + Vector<uint8_t> const *sessionId, + Vector<uint8_t> const *data) { + + mEventLock.lock(); + sp<DrmPluginListener> listener = mListener; + mEventLock.unlock(); + + if (listener != NULL) { + listener->sendEvent(eventType, extra, sessionId, data); + } + } + +} // namespace android + +#endif // DRM_API_H_ diff --git a/include/media/hardware/HDCPAPI.h b/include/media/hardware/HDCPAPI.h index 23e2bdd..147448e 100644 --- a/include/media/hardware/HDCPAPI.h +++ b/include/media/hardware/HDCPAPI.h @@ -22,6 +22,8 @@ namespace android { +// Two different kinds of modules are covered under the same HDCPModule +// structure below, a module either implements decryption or encryption. struct HDCPModule { typedef void (*ObserverFunc)(void *cookie, int msg, int ext1, int ext2); @@ -32,7 +34,8 @@ struct HDCPModule { // i.e. the HDCP session is now fully setup (AKE, Locality Check, // SKE and any authentication with repeaters completed) or failed. // ext1 should be a suitable error code (status_t), ext2 is - // unused. + // unused for ENCRYPTION and in the case of HDCP_INITIALIZATION_COMPLETE + // holds the local TCP port the module is listening on. HDCP_INITIALIZATION_COMPLETE, HDCP_INITIALIZATION_FAILED, @@ -46,6 +49,11 @@ struct HDCPModule { HDCP_REVOKED_CONNECTION, HDCP_TOPOLOGY_EXECEEDED, HDCP_UNKNOWN_ERROR, + + // DECRYPTION only: Indicates that a client has successfully connected, + // a secure session established and the module is ready to accept + // future calls to "decrypt". + HDCP_SESSION_ESTABLISHED, }; // Module can call the notification function to signal completion/failure @@ -55,24 +63,48 @@ struct HDCPModule { virtual ~HDCPModule() {}; - // Request to setup an HDCP session with the specified host listening - // on the specified port. - virtual status_t initAsync(const char *host, unsigned port) = 0; + // ENCRYPTION: Request to setup an HDCP session with the host specified + // by addr and listening on the specified port. + // DECRYPTION: Request to setup an HDCP session, addr is the interface + // address the module should bind its socket to. port will be 0. + // The module will pick the port to listen on itself and report its choice + // in the "ext2" argument of the HDCP_INITIALIZATION_COMPLETE callback. + virtual status_t initAsync(const char *addr, unsigned port) = 0; // Request to shutdown the active HDCP session. virtual status_t shutdownAsync() = 0; - // Encrypt a data according to the HDCP spec. The data is to be - // encrypted in-place, only size bytes of data should be read/write, - // even if the size is not a multiple of 128 bit (16 bytes). + // 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 + // of 128 bits (16 bytes). An equal number of encrypted bytes should be + // written to the buffer at "outData" (virtual address). // This operation is to be synchronous, i.e. this call does not return // until outData contains size bytes of encrypted data. // streamCTR will be assigned by the caller (to 0 for the first PES stream, // 1 for the second and so on) - // inputCTR will be maintained by the callee for each PES stream. + // inputCTR _will_be_maintained_by_the_callee_ for each PES stream. virtual status_t encrypt( const void *inData, size_t size, uint32_t streamCTR, - uint64_t *outInputCTR, void *outData) = 0; + uint64_t *outInputCTR, void *outData) { + return INVALID_OPERATION; + } + + // DECRYPTION only: + // Decrypt data according to the HDCP spec. + // "size" bytes of encrypted data are available at "inData" + // (virtual address), "size" may not be a multiple of 128 bits (16 bytes). + // An equal number of decrypted bytes should be written to the buffer + // at "outData" (virtual address). + // This operation is to be synchronous, i.e. this call does not return + // until outData contains size bytes of decrypted data. + // Both streamCTR and inputCTR will be provided by the caller. + virtual status_t decrypt( + const void *inData, size_t size, + uint32_t streamCTR, uint64_t inputCTR, + void *outData) { + return INVALID_OPERATION; + } private: HDCPModule(const HDCPModule &); @@ -81,13 +113,18 @@ private: } // namespace android -// A shared library exporting the following method should be included to +// A shared library exporting the following methods should be included to // support HDCP functionality. The shared library must be called // "libstagefright_hdcp.so", it will be dynamically loaded into the // mediaserver process. extern "C" { + // Create a module for ENCRYPTION. extern android::HDCPModule *createHDCPModule( void *cookie, android::HDCPModule::ObserverFunc); + + // Create a module for DECRYPTION. + extern android::HDCPModule *createHDCPModuleForDecryption( + void *cookie, android::HDCPModule::ObserverFunc); } #endif // HDCP_API_H_ diff --git a/include/media/openmax/OMX_IVCommon.h b/include/media/openmax/OMX_IVCommon.h index effbaae..85bf00d 100644 --- a/include/media/openmax/OMX_IVCommon.h +++ b/include/media/openmax/OMX_IVCommon.h @@ -160,6 +160,7 @@ typedef enum OMX_COLOR_FORMATTYPE { OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100, OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00, OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03, + OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002, OMX_COLOR_FormatMax = 0x7FFFFFFF } OMX_COLOR_FORMATTYPE; diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h new file mode 100644 index 0000000..d22df56 --- /dev/null +++ b/include/media/openmax/OMX_IndexExt.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** @file OMX_IndexExt.h - OpenMax IL version 1.1.2 + * The OMX_IndexExt header file contains extensions to the definitions + * for both applications and components . + */ + +#ifndef OMX_IndexExt_h +#define OMX_IndexExt_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include <OMX_Index.h> + + +/** Khronos standard extension indices. + +This enum lists the current Khronos extension indices to OpenMAX IL. +*/ +typedef enum OMX_INDEXEXTTYPE { + + /* Component parameters and configurations */ + OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000, + OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */ + OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */ + OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */ + + /* Port parameters and configurations */ + OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000, + + /* Audio parameters and configurations */ + OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000, + + /* Image parameters and configurations */ + OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000, + + /* Video parameters and configurations */ + OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000, + OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamVideoVp8, /**< reference: OMX_VIDEO_PARAM_VP8TYPE */ + OMX_IndexConfigVideoVp8ReferenceFrame, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */ + OMX_IndexConfigVideoVp8ReferenceFrameType, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */ + + /* Image & Video common configurations */ + OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000, + + /* Other configurations */ + OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000, + + /* Time configurations */ + OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000, + + OMX_IndexExtMax = 0x7FFFFFFF +} OMX_INDEXEXTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_IndexExt_h */ +/* File EOF */ diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h new file mode 100644 index 0000000..5e79b47 --- /dev/null +++ b/include/media/openmax/OMX_VideoExt.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2010 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** OMX_VideoExt.h - OpenMax IL version 1.1.2 + * The OMX_VideoExt header file contains extensions to the + * definitions used by both the application and the component to + * access video items. + */ + +#ifndef OMX_VideoExt_h +#define OMX_VideoExt_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include <OMX_Core.h> + +/** NALU Formats */ +typedef enum OMX_NALUFORMATSTYPE { + OMX_NaluFormatStartCodes = 1, + OMX_NaluFormatOneNaluPerBuffer = 2, + OMX_NaluFormatOneByteInterleaveLength = 4, + OMX_NaluFormatTwoByteInterleaveLength = 8, + OMX_NaluFormatFourByteInterleaveLength = 16, + OMX_NaluFormatCodingMax = 0x7FFFFFFF +} OMX_NALUFORMATSTYPE; + +/** NAL Stream Format */ +typedef struct OMX_NALSTREAMFORMATTYPE{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_NALUFORMATSTYPE eNaluFormat; +} OMX_NALSTREAMFORMATTYPE; + +/** Enum for standard video codingtype extensions */ +typedef enum OMX_VIDEO_CODINGEXTTYPE { + OMX_VIDEO_ExtCodingUnused = OMX_VIDEO_CodingKhronosExtensions, + OMX_VIDEO_CodingVP8, /**< VP8/WebM */ +} OMX_VIDEO_CODINGEXTTYPE; + +/** VP8 profiles */ +typedef enum OMX_VIDEO_VP8PROFILETYPE { + OMX_VIDEO_VP8ProfileMain = 0x01, + OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_VP8PROFILETYPE; + +/** VP8 levels */ +typedef enum OMX_VIDEO_VP8LEVELTYPE { + OMX_VIDEO_VP8Level_Version0 = 0x01, + OMX_VIDEO_VP8Level_Version1 = 0x02, + OMX_VIDEO_VP8Level_Version2 = 0x04, + OMX_VIDEO_VP8Level_Version3 = 0x08, + OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF +} OMX_VIDEO_VP8LEVELTYPE; + +/** VP8 Param */ +typedef struct OMX_VIDEO_PARAM_VP8TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_VP8PROFILETYPE eProfile; + OMX_VIDEO_VP8LEVELTYPE eLevel; + OMX_U32 nDCTPartitions; + OMX_BOOL bErrorResilientMode; +} OMX_VIDEO_PARAM_VP8TYPE; + +/** Structure for configuring VP8 reference frames */ +typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bPreviousFrameRefresh; + OMX_BOOL bGoldenFrameRefresh; + OMX_BOOL bAlternateFrameRefresh; + OMX_BOOL bUsePreviousFrame; + OMX_BOOL bUseGoldenFrame; + OMX_BOOL bUseAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMETYPE; + +/** Structure for querying VP8 reference frame type */ +typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bIsIntraFrame; + OMX_BOOL bIsGoldenOrAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_VideoExt_h */ +/* File EOF */ diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index a7eb48c..bf4bf03 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -24,7 +24,6 @@ #include <ui/Region.h> #include <ui/Rect.h> -#include <gui/ISurface.h> namespace android { @@ -51,7 +50,7 @@ struct layer_state_t { }; layer_state_t() - : surface(0), what(0), + : what(0), x(0), y(0), z(0), w(0), h(0), layerStack(0), alpha(0), flags(0), mask(0), reserved(0) @@ -70,7 +69,7 @@ struct layer_state_t { float dsdy; float dtdy; }; - SurfaceID surface; + sp<IBinder> surface; uint32_t what; float x; float y; @@ -114,7 +113,7 @@ struct DisplayState { uint32_t what; sp<IBinder> token; - sp<ISurfaceTexture> surface; + sp<IGraphicBufferProducer> surface; uint32_t layerStack; uint32_t orientation; Rect viewport; diff --git a/include/private/gui/SyncFeatures.h b/include/private/gui/SyncFeatures.h new file mode 100644 index 0000000..79fb75b --- /dev/null +++ b/include/private/gui/SyncFeatures.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SYNC_FEATURES_H +#define ANDROID_GUI_SYNC_FEATURES_H + +#include <utils/Singleton.h> +#include <utils/String8.h> + + +namespace android { +// ---------------------------------------------------------------------------- + +class SyncFeatures : public Singleton<SyncFeatures> { + friend class Singleton<SyncFeatures>; + bool mHasNativeFenceSync; + bool mHasFenceSync; + bool mHasWaitSync; + String8 mString; + SyncFeatures(); + +public: + bool useNativeFenceSync() const; + bool useFenceSync() const; + bool useWaitSync() const; + String8 toString() const; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SYNC_FEATURES_H diff --git a/include/ui/Fence.h b/include/ui/Fence.h index ff6cefe..60156e7 100644 --- a/include/ui/Fence.h +++ b/include/ui/Fence.h @@ -25,6 +25,7 @@ #include <ui/Rect.h> #include <utils/Flattenable.h> #include <utils/String8.h> +#include <utils/Timers.h> struct ANativeWindowBuffer; @@ -40,6 +41,10 @@ class Fence public: static const sp<Fence> NO_FENCE; + // TIMEOUT_NEVER may be passed to the wait method to indicate that it + // should wait indefinitely for the fence to signal. + enum { TIMEOUT_NEVER = -1 }; + // Construct a new Fence object with an invalid file descriptor. This // should be done when the Fence object will be set up by unflattening // serialized data. @@ -65,13 +70,10 @@ public: // waitForever is a convenience function for waiting forever for a fence to // signal (just like wait(TIMEOUT_NEVER)), but issuing an error to the // system log and fence state to the kernel log if the wait lasts longer - // than warningTimeout. The logname argument should be a string identifying + // than a warning timeout. + // The logname argument should be a string identifying // the caller and will be included in the log message. - status_t waitForever(unsigned int warningTimeout, const char* logname); - - // TIMEOUT_NEVER may be passed to the wait method to indicate that it - // should wait indefinitely for the fence to signal. - enum { TIMEOUT_NEVER = -1 }; + status_t waitForever(const char* logname); // merge combines two Fence objects, creating a new Fence object that // becomes signaled when both f1 and f2 are signaled (even if f1 or f2 is @@ -85,6 +87,12 @@ public: // be returned and errno will indicate the problem. int dup() const; + // getSignalTime returns the system monotonic clock time at which the + // fence transitioned to the signaled state. If the fence is not signaled + // then INT64_MAX is returned. If the fence is invalid or if an error + // occurs then -1 is returned. + nsecs_t getSignalTime() const; + // Flattenable interface size_t getFlattenedSize() const; size_t getFdCount() const; diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index f318cd8..e5ad1e0 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -24,6 +24,7 @@ #include <ui/PixelFormat.h> #include <ui/Rect.h> #include <utils/Flattenable.h> +#include <utils/RefBase.h> struct ANativeWindowBuffer; @@ -37,10 +38,8 @@ class GraphicBufferMapper; // =========================================================================== class GraphicBuffer - : public ANativeObjectBase< - ANativeWindowBuffer, - GraphicBuffer, - LightRefBase<GraphicBuffer> >, public Flattenable + : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >, + public Flattenable { public: @@ -93,6 +92,9 @@ public: status_t lock(uint32_t usage, void** vaddr); status_t lock(uint32_t usage, const Rect& rect, void** vaddr); + // For HAL_PIXEL_FORMAT_YCbCr_420_888 + status_t lockYCbCr(uint32_t usage, android_ycbcr *ycbcr); + status_t lockYCbCr(uint32_t usage, const Rect& rect, android_ycbcr *ycbcr); status_t unlock(); ANativeWindowBuffer* getNativeBuffer() const; @@ -124,7 +126,6 @@ private: friend class Surface; friend class BpSurface; friend class BnSurface; - friend class SurfaceTextureClient; friend class LightRefBase<GraphicBuffer>; GraphicBuffer(const GraphicBuffer& rhs); GraphicBuffer& operator = (const GraphicBuffer& rhs); diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h index 479cd3e..dffa788 100644 --- a/include/ui/GraphicBufferAllocator.h +++ b/include/ui/GraphicBufferAllocator.h @@ -84,7 +84,6 @@ private: static KeyedVector<buffer_handle_t, alloc_rec_t> sAllocList; friend class Singleton<GraphicBufferAllocator>; - friend class BufferLiberatorThread; GraphicBufferAllocator(); ~GraphicBufferAllocator(); diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h index 697a02a..99d8723 100644 --- a/include/ui/GraphicBufferMapper.h +++ b/include/ui/GraphicBufferMapper.h @@ -45,6 +45,9 @@ public: status_t lock(buffer_handle_t handle, int usage, const Rect& bounds, void** vaddr); + status_t lockYCbCr(buffer_handle_t handle, + int usage, const Rect& bounds, android_ycbcr *ycbcr); + status_t unlock(buffer_handle_t handle); // dumps information about the mapping of this handle diff --git a/include/ui/Region.h b/include/ui/Region.h index 43a4450..ce91f3b 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -39,7 +39,9 @@ public: Region(const Region& rhs); explicit Region(const Rect& rhs); ~Region(); - + + static Region createTJunctionFreeRegion(const Region& r); + Region& operator = (const Region& rhs); inline bool isEmpty() const { return getBounds().isEmpty(); } @@ -106,6 +108,10 @@ public: inline Region& operator += (const Point& pt); + // returns true if the regions share the same underlying storage + bool isTriviallyEqual(const Region& region) const; + + /* various ways to access the rectangle list */ diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h index f67648f..4eee14d 100644 --- a/include/utils/AndroidThreads.h +++ b/include/utils/AndroidThreads.h @@ -56,6 +56,9 @@ extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, size_t threadStackSize, android_thread_id_t *threadId); +// set the same of the running thread +extern void androidSetThreadName(const char* name); + // Used by the Java Runtime to control how threads are created, so that // they can be proper and lovely Java threads. typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, diff --git a/include/utils/BasicHashtable.h b/include/utils/BasicHashtable.h index fdf9738..7a6c96c 100644 --- a/include/utils/BasicHashtable.h +++ b/include/utils/BasicHashtable.h @@ -328,6 +328,14 @@ public: BasicHashtableImpl::rehash(minimumCapacity, loadFactor); } + /* Determines whether there is room to add another entry without rehashing. + * When this returns true, a subsequent add() operation is guaranteed to + * complete without performing a rehash. + */ + inline bool hasMoreRoom() const { + return mCapacity > mFilledBuckets; + } + protected: static inline const TEntry& entryFor(const Bucket& bucket) { return reinterpret_cast<const TEntry&>(bucket.entry); diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h index 079e20c..61dc832 100644 --- a/include/utils/CallStack.h +++ b/include/utils/CallStack.h @@ -35,6 +35,8 @@ public: }; CallStack(); + CallStack(const char* logtag, int32_t ignoreDepth=1, + int32_t maxDepth=MAX_DEPTH); CallStack(const CallStack& rhs); ~CallStack(); @@ -53,8 +55,8 @@ public: void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH); - // Dump a stack trace to the log - void dump(const char* prefix = 0) const; + // Dump a stack trace to the log using the supplied logtag + void dump(const char* logtag, const char* prefix = 0) const; // Return a string (possibly very long) containing the complete stack trace String8 toString(const char* prefix = 0) const; diff --git a/include/utils/Condition.h b/include/utils/Condition.h index 8852d53..e63ba7e 100644 --- a/include/utils/Condition.h +++ b/include/utils/Condition.h @@ -48,6 +48,11 @@ public: SHARED = 1 }; + enum WakeUpType { + WAKE_UP_ONE = 0, + WAKE_UP_ALL = 1 + }; + Condition(); Condition(int type); ~Condition(); @@ -57,6 +62,14 @@ public: status_t waitRelative(Mutex& mutex, nsecs_t reltime); // Signal the condition variable, allowing one thread to continue. void signal(); + // Signal the condition variable, allowing one or all threads to continue. + void signal(WakeUpType type) { + if (type == WAKE_UP_ONE) { + signal(); + } else { + broadcast(); + } + } // Signal the condition variable, allowing all threads to continue. void broadcast(); diff --git a/include/utils/JenkinsHash.h b/include/utils/JenkinsHash.h new file mode 100644 index 0000000..7da5dbd --- /dev/null +++ b/include/utils/JenkinsHash.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Implementation of Jenkins one-at-a-time hash function. These choices are + * optimized for code size and portability, rather than raw speed. But speed + * should still be quite good. + **/ + +#ifndef ANDROID_JENKINS_HASH_H +#define ANDROID_JENKINS_HASH_H + +#include <utils/TypeHelpers.h> + +namespace android { + +/* The Jenkins hash of a sequence of 32 bit words A, B, C is: + * Whiten(Mix(Mix(Mix(0, A), B), C)) */ + +inline uint32_t JenkinsHashMix(uint32_t hash, uint32_t data) { + hash += data; + hash += (hash << 10); + hash ^= (hash >> 6); + return hash; +} + +hash_t JenkinsHashWhiten(uint32_t hash); + +/* Helpful utility functions for hashing data in 32 bit chunks */ +uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size); + +uint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size); + +} + +#endif // ANDROID_JENKINS_HASH_H diff --git a/include/utils/LinearAllocator.h b/include/utils/LinearAllocator.h index cd2521d..4772bc8 100644 --- a/include/utils/LinearAllocator.h +++ b/include/utils/LinearAllocator.h @@ -30,11 +30,66 @@ namespace android { +/** + * A memory manager that internally allocates multi-kbyte buffers for placing objects in. It avoids + * the overhead of malloc when many objects are allocated. It is most useful when creating many + * small objects with a similar lifetime, and doesn't add significant overhead for large + * allocations. + */ class LinearAllocator { public: - void* alloc(size_t size) { return 0; } - void rewindIfLastAlloc(void* ptr, size_t allocSize) {} - void dumpMemoryStats(const char* prefix = "") {} + LinearAllocator(); + ~LinearAllocator(); + + /** + * Reserves and returns a region of memory of at least size 'size', aligning as needed. + * Typically this is used in an object's overridden new() method or as a replacement for malloc. + * + * The lifetime of the returned buffers is tied to that of the LinearAllocator. If calling + * delete() on an object stored in a buffer is needed, it should be overridden to use + * rewindIfLastAlloc() + */ + void* alloc(size_t size); + + /** + * Attempt to deallocate the given buffer, with the LinearAllocator attempting to rewind its + * state if possible. No destructors are called. + */ + void rewindIfLastAlloc(void* ptr, size_t allocSize); + + /** + * Dump memory usage statistics to the log (allocated and wasted space) + */ + void dumpMemoryStats(const char* prefix = ""); + + /** + * The number of bytes used for buffers allocated in the LinearAllocator (does not count space + * wasted) + */ + size_t usedSize() const { return mTotalAllocated - mWastedSpace; } + +private: + LinearAllocator(const LinearAllocator& other); + + class Page; + + Page* newPage(size_t pageSize); + bool fitsInCurrentPage(size_t size); + void ensureNext(size_t size); + void* start(Page *p); + void* end(Page* p); + + size_t mPageSize; + size_t mMaxAllocSize; + void* mNext; + Page* mCurrentPage; + Page* mPages; + + // Memory usage tracking + size_t mTotalAllocated; + size_t mWastedSpace; + size_t mPageCount; + size_t mDedicatedPageCount; }; }; // namespace android diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h new file mode 100644 index 0000000..302b929 --- /dev/null +++ b/include/utils/LruCache.h @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_LRU_CACHE_H +#define ANDROID_UTILS_LRU_CACHE_H + +#include <utils/BasicHashtable.h> +#include <utils/GenerationCache.h> +#include <utils/UniquePtr.h> + +namespace android { + +// OnEntryRemoved is defined in GenerationCache.h, but maybe should move here. + +template <typename TKey, typename TValue> +class LruCache { +public: + explicit LruCache(uint32_t maxCapacity); + + enum Capacity { + kUnlimitedCapacity, + }; + + void setOnEntryRemovedListener(OnEntryRemoved<TKey, TValue>* listener); + size_t size() const; + const TValue& get(const TKey& key); + bool put(const TKey& key, const TValue& value); + bool remove(const TKey& key); + bool removeOldest(); + void clear(); + + class Iterator { + public: + Iterator(const LruCache<TKey, TValue>& cache): mCache(cache), mIndex(-1) { + } + + bool next() { + mIndex = mCache.mTable->next(mIndex); + return mIndex != -1; + } + + size_t index() const { + return mIndex; + } + + const TValue& value() const { + return mCache.mTable->entryAt(mIndex).value; + } + + const TKey& key() const { + return mCache.mTable->entryAt(mIndex).key; + } + private: + const LruCache<TKey, TValue>& mCache; + size_t mIndex; + }; + +private: + LruCache(const LruCache& that); // disallow copy constructor + + struct Entry { + TKey key; + TValue value; + Entry* parent; + Entry* child; + + Entry(TKey key_, TValue value_) : key(key_), value(value_), parent(NULL), child(NULL) { + } + const TKey& getKey() const { return key; } + }; + + void attachToCache(Entry& entry); + void detachFromCache(Entry& entry); + void rehash(size_t newCapacity); + + UniquePtr<BasicHashtable<TKey, Entry> > mTable; + OnEntryRemoved<TKey, TValue>* mListener; + Entry* mOldest; + Entry* mYoungest; + uint32_t mMaxCapacity; + TValue mNullValue; +}; + +// Implementation is here, because it's fully templated +template <typename TKey, typename TValue> +LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), + mNullValue(NULL), mTable(new BasicHashtable<TKey, Entry>), mYoungest(NULL), mOldest(NULL), + mListener(NULL) { +}; + +template<typename K, typename V> +void LruCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener) { + mListener = listener; +} + +template <typename TKey, typename TValue> +size_t LruCache<TKey, TValue>::size() const { + return mTable->size(); +} + +template <typename TKey, typename TValue> +const TValue& LruCache<TKey, TValue>::get(const TKey& key) { + hash_t hash = hash_type(key); + ssize_t index = mTable->find(-1, hash, key); + if (index == -1) { + return mNullValue; + } + Entry& entry = mTable->editEntryAt(index); + detachFromCache(entry); + attachToCache(entry); + return entry.value; +} + +template <typename TKey, typename TValue> +bool LruCache<TKey, TValue>::put(const TKey& key, const TValue& value) { + if (mMaxCapacity != kUnlimitedCapacity && size() >= mMaxCapacity) { + removeOldest(); + } + + hash_t hash = hash_type(key); + ssize_t index = mTable->find(-1, hash, key); + if (index >= 0) { + return false; + } + if (!mTable->hasMoreRoom()) { + rehash(mTable->capacity() * 2); + } + + // Would it be better to initialize a blank entry and assign key, value? + Entry initEntry(key, value); + index = mTable->add(hash, initEntry); + Entry& entry = mTable->editEntryAt(index); + attachToCache(entry); + return true; +} + +template <typename TKey, typename TValue> +bool LruCache<TKey, TValue>::remove(const TKey& key) { + hash_t hash = hash_type(key); + ssize_t index = mTable->find(-1, hash, key); + if (index < 0) { + return false; + } + Entry& entry = mTable->editEntryAt(index); + if (mListener) { + (*mListener)(entry.key, entry.value); + } + detachFromCache(entry); + mTable->removeAt(index); + return true; +} + +template <typename TKey, typename TValue> +bool LruCache<TKey, TValue>::removeOldest() { + if (mOldest != NULL) { + return remove(mOldest->key); + // TODO: should probably abort if false + } + return false; +} + +template <typename TKey, typename TValue> +void LruCache<TKey, TValue>::clear() { + if (mListener) { + for (Entry* p = mOldest; p != NULL; p = p->child) { + (*mListener)(p->key, p->value); + } + } + mYoungest = NULL; + mOldest = NULL; + mTable->clear(); +} + +template <typename TKey, typename TValue> +void LruCache<TKey, TValue>::attachToCache(Entry& entry) { + if (mYoungest == NULL) { + mYoungest = mOldest = &entry; + } else { + entry.parent = mYoungest; + mYoungest->child = &entry; + mYoungest = &entry; + } +} + +template <typename TKey, typename TValue> +void LruCache<TKey, TValue>::detachFromCache(Entry& entry) { + if (entry.parent != NULL) { + entry.parent->child = entry.child; + } else { + mOldest = entry.child; + } + if (entry.child != NULL) { + entry.child->parent = entry.parent; + } else { + mYoungest = entry.parent; + } + + entry.parent = NULL; + entry.child = NULL; +} + +template <typename TKey, typename TValue> +void LruCache<TKey, TValue>::rehash(size_t newCapacity) { + UniquePtr<BasicHashtable<TKey, Entry> > oldTable(mTable.release()); + Entry* oldest = mOldest; + + mOldest = NULL; + mYoungest = NULL; + mTable.reset(new BasicHashtable<TKey, Entry>(newCapacity)); + for (Entry* p = oldest; p != NULL; p = p->child) { + put(p->key, p->value); + } +} + +} + +#endif // ANDROID_UTILS_LRU_CACHE_H diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h index de6fb39..dd201c8 100644 --- a/include/utils/Mutex.h +++ b/include/utils/Mutex.h @@ -91,10 +91,10 @@ private: inline Mutex::Mutex() { pthread_mutex_init(&mMutex, NULL); } -inline Mutex::Mutex(const char* name) { +inline Mutex::Mutex(__attribute__((unused)) const char* name) { pthread_mutex_init(&mMutex, NULL); } -inline Mutex::Mutex(int type, const char* name) { +inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { if (type == SHARED) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); diff --git a/include/utils/RWLock.h b/include/utils/RWLock.h index a5abea2..90beb5f 100644 --- a/include/utils/RWLock.h +++ b/include/utils/RWLock.h @@ -84,10 +84,10 @@ private: inline RWLock::RWLock() { pthread_rwlock_init(&mRWLock, NULL); } -inline RWLock::RWLock(const char* name) { +inline RWLock::RWLock(__attribute__((unused)) const char* name) { pthread_rwlock_init(&mRWLock, NULL); } -inline RWLock::RWLock(int type, const char* name) { +inline RWLock::RWLock(int type, __attribute__((unused)) const char* name) { if (type == SHARED) { pthread_rwlockattr_t attr; pthread_rwlockattr_init(&attr); diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h index 99f5182..033fe67 100644 --- a/include/utils/RefBase.h +++ b/include/utils/RefBase.h @@ -52,12 +52,16 @@ inline bool operator _op_ (const U* o) const { \ } // --------------------------------------------------------------------------- -class ReferenceMover; -class ReferenceConverterBase { + +class ReferenceRenamer { +protected: + // destructor is purposedly not virtual so we avoid code overhead from + // subclasses; we have to make it protected to guarantee that it + // cannot be called from this base class (and to make strict compilers + // happy). + ~ReferenceRenamer() { } public: - virtual size_t getReferenceTypeSize() const = 0; - virtual void* getReferenceBase(void const*) const = 0; - inline virtual ~ReferenceConverterBase() { } + virtual void operator()(size_t i) const = 0; }; // --------------------------------------------------------------------------- @@ -144,17 +148,23 @@ protected: virtual void onLastWeakRef(const void* id); private: - friend class ReferenceMover; - static void moveReferences(void* d, void const* s, size_t n, - const ReferenceConverterBase& caster); - -private: friend class weakref_type; class weakref_impl; RefBase(const RefBase& o); RefBase& operator=(const RefBase& o); +private: + friend class ReferenceMover; + + static void renameRefs(size_t n, const ReferenceRenamer& renamer); + + static void renameRefId(weakref_type* ref, + const void* old_id, const void* new_id); + + static void renameRefId(RefBase* ref, + const void* old_id, const void* new_id); + weakref_impl* const mRefs; }; @@ -165,10 +175,10 @@ class LightRefBase { public: inline LightRefBase() : mCount(0) { } - inline void incStrong(const void* id) const { + inline void incStrong(__attribute__((unused)) const void* id) const { android_atomic_inc(&mCount); } - inline void decStrong(const void* id) const { + inline void decStrong(__attribute__((unused)) const void* id) const { if (android_atomic_dec(&mCount) == 1) { delete static_cast<const T*>(this); } @@ -185,8 +195,9 @@ protected: private: friend class ReferenceMover; - inline static void moveReferences(void* d, void const* s, size_t n, - const ReferenceConverterBase& caster) { } + inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } + inline static void renameRefId(T* ref, + const void* old_id, const void* new_id) { } private: mutable volatile int32_t mCount; @@ -455,42 +466,48 @@ inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) // this class just serves as a namespace so TYPE::moveReferences can stay // private. - class ReferenceMover { - // StrongReferenceCast and WeakReferenceCast do the impedance matching - // between the generic (void*) implementation in Refbase and the strongly typed - // template specializations below. - - template <typename TYPE> - struct StrongReferenceCast : public ReferenceConverterBase { - virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); } - virtual void* getReferenceBase(void const* p) const { - sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p)); - return static_cast<typename TYPE::basetype *>(sptr->get()); - } - }; - - template <typename TYPE> - struct WeakReferenceCast : public ReferenceConverterBase { - virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } - virtual void* getReferenceBase(void const* p) const { - wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); - return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); - } - }; - public: + // it would be nice if we could make sure no extra code is generated + // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: + // Using a sp<RefBase> override doesn't work; it's a bit like we wanted + // a template<typename TYPE inherits RefBase> template... + template<typename TYPE> static inline void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { + + class Renamer : public ReferenceRenamer { + sp<TYPE>* d; + sp<TYPE> const* s; + virtual void operator()(size_t i) const { + // The id are known to be the sp<>'s this pointer + TYPE::renameRefId(d[i].get(), &s[i], &d[i]); + } + public: + Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { } + }; + memmove(d, s, n*sizeof(sp<TYPE>)); - StrongReferenceCast<TYPE> caster; - TYPE::moveReferences(d, s, n, caster); + TYPE::renameRefs(n, Renamer(d, s)); } + + template<typename TYPE> static inline void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { + + class Renamer : public ReferenceRenamer { + wp<TYPE>* d; + wp<TYPE> const* s; + virtual void operator()(size_t i) const { + // The id are known to be the wp<>'s this pointer + TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); + } + public: + Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { } + }; + memmove(d, s, n*sizeof(wp<TYPE>)); - WeakReferenceCast<TYPE> caster; - TYPE::moveReferences(d, s, n, caster); + TYPE::renameRefs(n, Renamer(d, s)); } }; diff --git a/include/utils/Thread.h b/include/utils/Thread.h index 4a34abd..df30611 100644 --- a/include/utils/Thread.h +++ b/include/utils/Thread.h @@ -67,6 +67,9 @@ public: // Do not call from this object's thread; will return WOULD_BLOCK in that case. status_t join(); + // Indicates whether this thread is running or not. + bool isRunning() const; + #ifdef HAVE_ANDROID_OS // Return the thread's kernel ID, same as the thread itself calling gettid() or // androidGetTid(), or -1 if the thread is not running. diff --git a/include/utils/Trace.h b/include/utils/Trace.h index 41bce00..49578c4 100644 --- a/include/utils/Trace.h +++ b/include/utils/Trace.h @@ -27,166 +27,31 @@ #include <cutils/compiler.h> #include <utils/threads.h> +#include <cutils/trace.h> -// The ATRACE_TAG macro can be defined before including this header to trace -// using one of the tags defined below. It must be defined to one of the -// following ATRACE_TAG_* macros. The trace tag is used to filter tracing in -// userland to avoid some of the runtime cost of tracing when it is not desired. -// -// Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always -// being enabled - this should ONLY be done for debug code, as userland tracing -// has a performance cost even when the trace is not being recorded. Defining -// ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result -// in the tracing always being disabled. -// -// These tags must be kept in sync with frameworks/base/core/java/android/os/Trace.java. -#define ATRACE_TAG_NEVER 0 // The "never" tag is never enabled. -#define ATRACE_TAG_ALWAYS (1<<0) // The "always" tag is always enabled. -#define ATRACE_TAG_GRAPHICS (1<<1) -#define ATRACE_TAG_INPUT (1<<2) -#define ATRACE_TAG_VIEW (1<<3) -#define ATRACE_TAG_WEBVIEW (1<<4) -#define ATRACE_TAG_WINDOW_MANAGER (1<<5) -#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6) -#define ATRACE_TAG_SYNC_MANAGER (1<<7) -#define ATRACE_TAG_AUDIO (1<<8) -#define ATRACE_TAG_VIDEO (1<<9) -#define ATRACE_TAG_CAMERA (1<<10) -#define ATRACE_TAG_LAST ATRACE_TAG_CAMERA +// See <cutils/trace.h> for more ATRACE_* macros. -#define ATRACE_TAG_NOT_READY (1LL<<63) // Reserved for use during init - -#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST) - -#ifndef ATRACE_TAG -#define ATRACE_TAG ATRACE_TAG_NEVER -#elif ATRACE_TAG > ATRACE_TAG_LAST -#error ATRACE_TAG must be defined to be one of the tags defined in utils/Trace.h -#endif - -// ATRACE_CALL traces the beginning and end of the current function. To trace -// the correct start and end times this macro should be the first line of the -// function body. -#define ATRACE_CALL() android::ScopedTrace ___tracer(ATRACE_TAG, __FUNCTION__) - -// ATRACE_NAME traces the beginning and end of the current function. To trace -// the correct start and end times this macro should be the first line of the -// function body. +// ATRACE_NAME traces the beginning and end of the current scope. To trace +// the correct start and end times this macro should be declared first in the +// scope body. #define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name) - -// ATRACE_INT traces a named integer value. This can be used to track how the -// value changes over time in a trace. -#define ATRACE_INT(name, value) android::Tracer::traceCounter(ATRACE_TAG, name, value) - -// ATRACE_ENABLED returns true if the trace tag is enabled. It can be used as a -// guard condition around more expensive trace calculations. -#define ATRACE_ENABLED() android::Tracer::isTagEnabled(ATRACE_TAG) +// ATRACE_CALL is an ATRACE_NAME that uses the current function name. +#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__) namespace android { -class Tracer { - -public: - - static uint64_t getEnabledTags() { - initIfNeeded(); - return sEnabledTags; - } - - static inline bool isTagEnabled(uint64_t tag) { - initIfNeeded(); - return sEnabledTags & tag; - } - - static inline void traceCounter(uint64_t tag, const char* name, - int32_t value) { - if (CC_UNLIKELY(isTagEnabled(tag))) { - char buf[1024]; - snprintf(buf, 1024, "C|%d|%s|%d", getpid(), name, value); - write(sTraceFD, buf, strlen(buf)); - } - } - - static inline void traceBegin(uint64_t tag, const char* name) { - if (CC_UNLIKELY(isTagEnabled(tag))) { - char buf[1024]; - size_t len = snprintf(buf, 1024, "B|%d|%s", getpid(), name); - write(sTraceFD, buf, len); - } - } - - static inline void traceEnd(uint64_t tag) { - if (CC_UNLIKELY(isTagEnabled(tag))) { - char buf = 'E'; - write(sTraceFD, &buf, 1); - } - } - -private: - - static inline void initIfNeeded() { - if (!android_atomic_acquire_load(&sIsReady)) { - init(); - } - } - - static void changeCallback(); - - // init opens the trace marker file for writing and reads the - // atrace.tags.enableflags system property. It does this only the first - // time it is run, using sMutex for synchronization. - static void init(); - - // retrieve the current value of the system property. - static void loadSystemProperty(); - - // sIsReady is a boolean value indicating whether a call to init() has - // completed in this process. It is initialized to 0 and set to 1 when the - // first init() call completes. It is set to 1 even if a failure occurred - // in init (e.g. the trace marker file couldn't be opened). - // - // This should be checked by all tracing functions using an atomic acquire - // load operation before calling init(). This check avoids the need to lock - // a mutex each time a trace function gets called. - static volatile int32_t sIsReady; - - // sTraceFD is the file descriptor used to write to the kernel's trace - // buffer. It is initialized to -1 and set to an open file descriptor in - // init() while a lock on sMutex is held. - // - // This should only be used by a trace function after init() has - // successfully completed. - static int sTraceFD; - - // sEnabledTags is the set of tag bits for which tracing is currently - // enabled. It is initialized to 0 and set based on the - // atrace.tags.enableflags system property in init() while a lock on sMutex - // is held. - // - // This should only be used by a trace function after init() has - // successfully completed. - // - // This value is only ever non-zero when tracing is initialized and sTraceFD is not -1. - static uint64_t sEnabledTags; - - // sMutex is used to protect the execution of init(). - static Mutex sMutex; -}; - class ScopedTrace { - public: - inline ScopedTrace(uint64_t tag, const char* name) : - mTag(tag) { - Tracer::traceBegin(mTag, name); - } +inline ScopedTrace(uint64_t tag, const char* name) + : mTag(tag) { + atrace_begin(mTag,name); +} - inline ~ScopedTrace() { - Tracer::traceEnd(mTag); - } +inline ~ScopedTrace() { + atrace_end(mTag); +} private: - uint64_t mTag; }; diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h index 2bf33c3..13c9081 100644 --- a/include/utils/TypeHelpers.h +++ b/include/utils/TypeHelpers.h @@ -291,7 +291,7 @@ ANDROID_INT64_HASH(uint64_t) ANDROID_REINTERPRET_HASH(float, uint32_t) ANDROID_REINTERPRET_HASH(double, uint64_t) -template <typename T> inline hash_t hash_type(const T*& value) { +template <typename T> inline hash_t hash_type(T* const & value) { return hash_type(uintptr_t(value)); } diff --git a/include/utils/Vector.h b/include/utils/Vector.h index f3020d6..ed7b725 100644 --- a/include/utils/Vector.h +++ b/include/utils/Vector.h @@ -80,7 +80,13 @@ public: //! sets the capacity. capacity can never be reduced less than size() inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } - /*! + /*! + * set the size of the vector. items are appended with the default + * constructor, or removed from the end as needed. + */ + inline ssize_t resize(size_t size) { return VectorImpl::resize(size); } + + /*! * C-style array access */ diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h index c4ec2ff..9bc50e6 100644 --- a/include/utils/VectorImpl.h +++ b/include/utils/VectorImpl.h @@ -64,6 +64,7 @@ public: inline bool isEmpty() const { return mCount == 0; } size_t capacity() const; ssize_t setCapacity(size_t size); + ssize_t resize(size_t size); /*! append/insert another vector or array */ ssize_t insertVectorAt(const VectorImpl& vector, size_t index); |