implement: "Add an ANativeWindow API for SurfaceFlinger to suggest an optimal buffer orientation"

Bug: 4487161
Change-Id: I883f34efe542c2a566d04966f873374f40c50092
This commit is contained in:
Mathias Agopian 2011-07-19 15:24:46 -07:00
parent 933389f758
commit 97c602c5af
12 changed files with 147 additions and 68 deletions

View File

@ -78,7 +78,12 @@ protected:
// client for this buffer. The timestamp is measured in nanoseconds, and
// must be monotonically increasing. Its other properties (zero point, etc)
// are client-dependent, and should be documented by the client.
virtual status_t queueBuffer(int slot, int64_t timestamp) = 0;
//
// outWidth, outHeight and outTransform are filed with the default width
// default height of the window and current transform applied to buffers,
// respectively.
virtual status_t queueBuffer(int slot, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
// cancelBuffer indicates that the client does not wish to fill in the
// buffer associated with slot and transfers ownership of the slot back to

View File

@ -84,7 +84,8 @@ public:
// nanoseconds, and must be monotonically increasing. Its other semantics
// (zero point, etc) are client-dependent and should be documented by the
// client.
virtual status_t queueBuffer(int buf, int64_t timestamp);
virtual status_t queueBuffer(int buf, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
virtual void cancelBuffer(int buf);
virtual status_t setCrop(const Rect& reg);
virtual status_t setTransform(uint32_t transform);

View File

@ -151,6 +151,18 @@ private:
// dequeued format or to mReqFormat if no buffer was dequeued.
uint32_t mQueryFormat;
// mDefaultWidth is default width of the window, regardless of the
// set_dimension call
uint32_t mDefaultWidth;
// mDefaultHeight is default width of the window, regardless of the
// set_dimension call
uint32_t mDefaultHeight;
// mTransformHint is the transform probably applied to buffers of this
// window. this is only a hint, actual transform may differ.
uint32_t mTransformHint;
// 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.

View File

@ -93,12 +93,16 @@ public:
return result;
}
virtual status_t queueBuffer(int buf, int64_t timestamp) {
virtual status_t queueBuffer(int buf, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(buf);
data.writeInt64(timestamp);
remote()->transact(QUEUE_BUFFER, data, &reply);
*outWidth = reply.readInt32();
*outHeight = reply.readInt32();
*outTransform = reply.readInt32();
status_t result = reply.readInt32();
return result;
}
@ -226,7 +230,12 @@ status_t BnSurfaceTexture::onTransact(
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int buf = data.readInt32();
int64_t timestamp = data.readInt64();
status_t result = queueBuffer(buf, timestamp);
uint32_t outWidth, outHeight, outTransform;
status_t result = queueBuffer(buf, timestamp,
&outWidth, &outHeight, &outTransform);
reply->writeInt32(outWidth);
reply->writeInt32(outHeight);
reply->writeInt32(outTransform);
reply->writeInt32(result);
return NO_ERROR;
} break;

View File

@ -402,7 +402,8 @@ status_t SurfaceTexture::setSynchronousMode(bool enabled) {
return err;
}
status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
LOGV("SurfaceTexture::queueBuffer");
sp<FrameAvailableListener> listener;
@ -463,6 +464,11 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
if (listener != 0) {
listener->onFrameAvailable();
}
*outWidth = mDefaultWidth;
*outHeight = mDefaultHeight;
*outTransform = 0;
return OK;
}

View File

@ -222,26 +222,38 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
if (i < 0) {
return i;
}
mSurfaceTexture->queueBuffer(i, timestamp);
mSurfaceTexture->queueBuffer(i, timestamp,
&mDefaultWidth, &mDefaultHeight, &mTransformHint);
return OK;
}
int SurfaceTextureClient::query(int what, int* value) const {
LOGV("SurfaceTextureClient::query");
switch (what) {
case NATIVE_WINDOW_FORMAT:
if (mReqFormat) {
*value = mReqFormat;
return NO_ERROR;
{ // scope for the lock
Mutex::Autolock lock(mMutex);
switch (what) {
case NATIVE_WINDOW_FORMAT:
if (mReqFormat) {
*value = mReqFormat;
return NO_ERROR;
}
break;
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
*value = 0;
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_WIDTH:
*value = mDefaultWidth;
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_HEIGHT:
*value = mDefaultHeight;
return NO_ERROR;
case NATIVE_WINDOW_TRANSFORM_HINT:
*value = mTransformHint;
return NO_ERROR;
}
break;
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
// TODO: this is not needed anymore
*value = 0;
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
return NO_ERROR;
}
return mSurfaceTexture->query(what, value);
}

View File

@ -289,6 +289,18 @@ int FramebufferNativeWindow::query(const ANativeWindow* window,
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_FRAMEBUFFER;
return NO_ERROR;
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
*value = 0;
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_WIDTH:
*value = fb->width;
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_HEIGHT:
*value = fb->height;
return NO_ERROR;
case NATIVE_WINDOW_TRANSFORM_HINT:
*value = 0;
return NO_ERROR;
}
*value = 0;
return BAD_VALUE;

View File

@ -44,10 +44,6 @@
namespace android {
template <typename T> inline T min(T a, T b) {
return a<b ? a : b;
}
// ---------------------------------------------------------------------------
Layer::Layer(SurfaceFlinger* flinger,
@ -457,13 +453,22 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
// FIXME: mPostedDirtyRegion = dirty & bounds
mPostedDirtyRegion.set(front.w, front.h);
sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
if ((newFrontBuffer->getWidth() == front.requested_w &&
newFrontBuffer->getHeight() == front.requested_h) ||
isFixedSize())
if ((front.w != front.requested_w) ||
(front.h != front.requested_h))
{
if ((front.w != front.requested_w) ||
(front.h != front.requested_h))
// check that we received a buffer of the right size
// (Take the buffer's orientation into account)
sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
uint32_t bufWidth = newFrontBuffer->getWidth();
uint32_t bufHeight = newFrontBuffer->getHeight();
if (mCurrentTransform & Transform::ROT_90) {
swap(bufWidth, bufHeight);
}
if (isFixedSize() ||
(bufWidth == front.requested_w &&
bufHeight == front.requested_h))
{
// Here we pretend the transaction happened by updating the
// current and drawing states. Drawing state is only accessed
@ -483,10 +488,10 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
// recompute visible region
recomputeVisibleRegions = true;
}
// we now have the correct size, unfreeze the screen
mFreezeLock.clear();
// we now have the correct size, unfreeze the screen
mFreezeLock.clear();
}
}
}
}

View File

@ -52,6 +52,20 @@ status_t SurfaceTextureLayer::setBufferCount(int bufferCount) {
return res;
}
status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
status_t res = SurfaceTexture::queueBuffer(buf, timestamp,
outWidth, outHeight, outTransform);
sp<Layer> layer(mLayer.promote());
if (layer != NULL) {
*outTransform = layer->getOrientation();
}
return res;
}
status_t SurfaceTextureLayer::dequeueBuffer(int *buf,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {

View File

@ -45,6 +45,9 @@ public:
virtual status_t setBufferCount(int bufferCount);
protected:
virtual status_t queueBuffer(int buf, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage);
};

View File

@ -20,6 +20,7 @@
#include <utils/String8.h>
#include <ui/Region.h>
#include "clz.h"
#include "Transform.h"
// ---------------------------------------------------------------------------
@ -28,42 +29,6 @@ namespace android {
// ---------------------------------------------------------------------------
template <typename T>
static inline T min(T a, T b) {
return a<b ? a : b;
}
template <typename T>
static inline T min(T a, T b, T c) {
return min(a, min(b, c));
}
template <typename T>
static inline T min(T a, T b, T c, T d) {
return min(a, b, min(c, d));
}
template <typename T>
static inline T max(T a, T b) {
return a>b ? a : b;
}
template <typename T>
static inline T max(T a, T b, T c) {
return max(a, max(b, c));
}
template <typename T>
static inline T max(T a, T b, T c, T d) {
return max(a, b, max(c, d));
}
template <typename T>
static inline
void swap(T& a, T& b) {
T t(a);
a = b;
b = t;
}
// ---------------------------------------------------------------------------
Transform::Transform() {
reset();
}

View File

@ -24,6 +24,41 @@ int inline clz(int32_t x) {
return __builtin_clz(x);
}
template <typename T>
static inline T min(T a, T b) {
return a<b ? a : b;
}
template <typename T>
static inline T min(T a, T b, T c) {
return min(a, min(b, c));
}
template <typename T>
static inline T min(T a, T b, T c, T d) {
return min(a, b, min(c, d));
}
template <typename T>
static inline T max(T a, T b) {
return a>b ? a : b;
}
template <typename T>
static inline T max(T a, T b, T c) {
return max(a, max(b, c));
}
template <typename T>
static inline T max(T a, T b, T c, T d) {
return max(a, b, max(c, d));
}
template <typename T>
static inline
void swap(T& a, T& b) {
T t(a);
a = b;
b = t;
}
}; // namespace android
#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */