implement: "Add an ANativeWindow API for SurfaceFlinger to suggest an optimal buffer orientation"
Bug: 4487161 Change-Id: I883f34efe542c2a566d04966f873374f40c50092
This commit is contained in:
parent
933389f758
commit
97c602c5af
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user