summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/ui/FramebufferNativeWindow.h1
-rw-r--r--include/ui/Surface.h6
-rw-r--r--include/ui/egl/android_natives.h15
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp18
-rw-r--r--libs/ui/Surface.cpp35
-rw-r--r--opengl/libagl/egl.cpp50
6 files changed, 104 insertions, 21 deletions
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index e72357a..cb9bf94 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -62,6 +62,7 @@ private:
static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
+ static int query(android_native_window_t* window, int what, int* value);
framebuffer_device_t* fbDev;
alloc_device_t* grDev;
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 8c4f63d..156d453 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -115,6 +115,8 @@ private:
sp<ISurface> mSurface;
SurfaceID mToken;
uint32_t mIdentity;
+ uint32_t mWidth;
+ uint32_t mHeight;
PixelFormat mFormat;
uint32_t mFlags;
mutable Mutex mLock;
@@ -192,10 +194,12 @@ private:
static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
+ static int query(android_native_window_t* window, int what, int* value);
int dequeueBuffer(android_native_buffer_t** buffer);
int lockBuffer(android_native_buffer_t* buffer);
int queueBuffer(android_native_buffer_t* buffer);
+ int query(int what, int* value);
status_t dequeueBuffer(sp<SurfaceBuffer>* buffer);
status_t lockBuffer(const sp<SurfaceBuffer>& buffer);
@@ -209,6 +213,8 @@ private:
sp<SurfaceBuffer> mLockedBuffer;
SurfaceID mToken;
uint32_t mIdentity;
+ uint32_t mWidth;
+ uint32_t mHeight;
PixelFormat mFormat;
uint32_t mFlags;
mutable Region mDirtyRegion;
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0398ea7..a3a1316 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -60,6 +60,12 @@ struct android_native_base_t
// ---------------------------------------------------------------------------
+/* attributes queriable with query() */
+enum {
+ NATIVE_WINDOW_WIDTH = 0,
+ NATIVE_WINDOW_HEIGHT = 1
+};
+
struct android_native_window_t
{
#ifdef __cplusplus
@@ -129,8 +135,15 @@ struct android_native_window_t
int (*queueBuffer)(struct android_native_window_t* window,
struct android_native_buffer_t* buffer);
+ /*
+ * hook used to retrieve information about the native window.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*query)(struct android_native_window_t* window,
+ int what, int* value);
- void* reserved_proc[5];
+ void* reserved_proc[4];
};
// ---------------------------------------------------------------------------
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 8c8fd6b..8b7ea21 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -124,6 +124,7 @@ FramebufferNativeWindow::FramebufferNativeWindow()
android_native_window_t::dequeueBuffer = dequeueBuffer;
android_native_window_t::lockBuffer = lockBuffer;
android_native_window_t::queueBuffer = queueBuffer;
+ android_native_window_t::query = query;
}
FramebufferNativeWindow::~FramebufferNativeWindow() {
@@ -198,6 +199,23 @@ int FramebufferNativeWindow::queueBuffer(android_native_window_t* window,
return res;
}
+int FramebufferNativeWindow::query(android_native_window_t* window,
+ int what, int* value)
+{
+ FramebufferNativeWindow* self = getSelf(window);
+ Mutex::Autolock _l(self->mutex);
+ framebuffer_device_t* fb = self->fbDev;
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ *value = fb->width;
+ return NO_ERROR;
+ case NATIVE_WINDOW_HEIGHT:
+ *value = fb->height;
+ return NO_ERROR;
+ }
+ return BAD_VALUE;
+}
+
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index aef47fd..04ab64c 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -180,7 +180,7 @@ SurfaceControl::SurfaceControl(
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
: mClient(client), mSurface(surface),
mToken(data.token), mIdentity(data.identity),
- mFormat(format), mFlags(flags)
+ mWidth(w), mHeight(h), mFormat(format), mFlags(flags)
{
}
@@ -338,6 +338,8 @@ status_t SurfaceControl::writeSurfaceToParcel(
uint32_t format = 0;
SurfaceID token = -1;
uint32_t identity = 0;
+ uint32_t width = 0;
+ uint32_t height = 0;
sp<SurfaceComposerClient> client;
sp<ISurface> sur;
if (SurfaceControl::isValid(control)) {
@@ -345,6 +347,8 @@ status_t SurfaceControl::writeSurfaceToParcel(
identity = control->mIdentity;
client = control->mClient;
sur = control->mSurface;
+ width = control->mWidth;
+ height = control->mHeight;
format = control->mFormat;
flags = control->mFlags;
}
@@ -352,6 +356,8 @@ status_t SurfaceControl::writeSurfaceToParcel(
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
parcel->writeInt32(token);
parcel->writeInt32(identity);
+ parcel->writeInt32(width);
+ parcel->writeInt32(height);
parcel->writeInt32(format);
parcel->writeInt32(flags);
return NO_ERROR;
@@ -373,6 +379,7 @@ sp<Surface> SurfaceControl::getSurface() const
Surface::Surface(const sp<SurfaceControl>& surface)
: mClient(surface->mClient), mSurface(surface->mSurface),
mToken(surface->mToken), mIdentity(surface->mIdentity),
+ mWidth(surface->mWidth), mHeight(surface->mHeight),
mFormat(surface->mFormat), mFlags(surface->mFlags),
mBufferMapper(BufferMapper::get())
{
@@ -386,6 +393,8 @@ Surface::Surface(const Parcel& parcel)
mSurface = interface_cast<ISurface>(parcel.readStrongBinder());
mToken = parcel.readInt32();
mIdentity = parcel.readInt32();
+ mWidth = parcel.readInt32();
+ mHeight = parcel.readInt32();
mFormat = parcel.readInt32();
mFlags = parcel.readInt32();
@@ -401,6 +410,7 @@ void Surface::init()
android_native_window_t::dequeueBuffer = dequeueBuffer;
android_native_window_t::lockBuffer = lockBuffer;
android_native_window_t::queueBuffer = queueBuffer;
+ android_native_window_t::query = query;
mSwapRectangle.makeInvalid();
DisplayInfo dinfo;
SurfaceComposerClient::getDisplayInfo(0, &dinfo);
@@ -492,6 +502,13 @@ int Surface::queueBuffer(android_native_window_t* window,
return self->queueBuffer(buffer);
}
+int Surface::query(android_native_window_t* window,
+ int what, int* value)
+{
+ Surface* self = getSelf(window);
+ return self->query(what, value);
+}
+
// ----------------------------------------------------------------------------
status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer)
@@ -499,6 +516,9 @@ status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer)
android_native_buffer_t* out;
status_t err = dequeueBuffer(&out);
*buffer = SurfaceBuffer::getSelf(out);
+ // reset the width/height with the what we get from the buffer
+ mWidth = uint32_t(out->width);
+ mHeight = uint32_t(out->height);
return err;
}
@@ -586,6 +606,19 @@ int Surface::queueBuffer(android_native_buffer_t* buffer)
return NO_ERROR;
}
+int Surface::query(int what, int* value)
+{
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ *value = int(mWidth);
+ return NO_ERROR;
+ case NATIVE_WINDOW_HEIGHT:
+ *value = int(mHeight);
+ return NO_ERROR;
+ }
+ return BAD_VALUE;
+}
+
// ----------------------------------------------------------------------------
status_t Surface::lock(SurfaceInfo* info, bool blocking) {
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 7afcae7..b0e54d8 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -216,8 +216,8 @@ struct egl_window_surface_v2_t : public egl_surface_t
virtual EGLBoolean bindReadSurface(ogles_context_t* gl);
virtual void connect();
virtual void disconnect();
- virtual EGLint getWidth() const { return buffer->width; }
- virtual EGLint getHeight() const { return buffer->height; }
+ virtual EGLint getWidth() const { return width; }
+ virtual EGLint getHeight() const { return height; }
virtual EGLint getHorizontalResolution() const;
virtual EGLint getVerticalResolution() const;
virtual EGLint getRefreshRate() const;
@@ -365,14 +365,32 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
// keep a reference on the window
nativeWindow->common.incRef(&nativeWindow->common);
+ nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &width);
+ nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &height);
+}
+egl_window_surface_v2_t::~egl_window_surface_v2_t() {
+ if (buffer) {
+ buffer->common.decRef(&buffer->common);
+ }
+ if (previousBuffer) {
+ previousBuffer->common.decRef(&previousBuffer->common);
+ }
+ nativeWindow->common.decRef(&nativeWindow->common);
+ if (blitengine) {
+ copybit_close(blitengine);
+ }
+}
+
+void egl_window_surface_v2_t::connect()
+{
// dequeue a buffer
nativeWindow->dequeueBuffer(nativeWindow, &buffer);
// allocate a corresponding depth-buffer
width = buffer->width;
height = buffer->height;
- if (depthFormat) {
+ if (depth.format) {
depth.width = width;
depth.height = height;
depth.stride = depth.width; // use the width here
@@ -385,23 +403,7 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
// keep a reference on the buffer
buffer->common.incRef(&buffer->common);
-}
-egl_window_surface_v2_t::~egl_window_surface_v2_t() {
- if (buffer) {
- buffer->common.decRef(&buffer->common);
- }
- if (previousBuffer) {
- previousBuffer->common.decRef(&previousBuffer->common);
- }
- nativeWindow->common.decRef(&nativeWindow->common);
- if (blitengine) {
- copybit_close(blitengine);
- }
-}
-
-void egl_window_surface_v2_t::connect()
-{
// Lock the buffer
nativeWindow->lockBuffer(nativeWindow, buffer);
// pin the buffer down
@@ -420,6 +422,16 @@ void egl_window_surface_v2_t::disconnect()
bits = NULL;
unlock(buffer);
}
+ // enqueue the last frame
+ nativeWindow->queueBuffer(nativeWindow, buffer);
+ if (buffer) {
+ buffer->common.decRef(&buffer->common);
+ buffer = 0;
+ }
+ if (previousBuffer) {
+ previousBuffer->common.decRef(&previousBuffer->common);
+ previousBuffer = 0;
+ }
}
status_t egl_window_surface_v2_t::lock(