summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-09-04 15:05:38 -0700
committerMathias Agopian <mathias@google.com>2012-09-04 16:59:06 -0700
commitda8d0a5c0cf9d41915d3b106cad4aaec3e767c11 (patch)
treeff32d3624ef19dcd8677dfab3f1b85a3dd0b2b8b
parent493db47929cdd805339e453062fef265d8985692 (diff)
downloadframeworks_native-da8d0a5c0cf9d41915d3b106cad4aaec3e767c11.zip
frameworks_native-da8d0a5c0cf9d41915d3b106cad4aaec3e767c11.tar.gz
frameworks_native-da8d0a5c0cf9d41915d3b106cad4aaec3e767c11.tar.bz2
implement display viewport and frame
note: viewport clipping is not implemented yet Change-Id: I7fde7c4de075d409d95c48bb20ba8ee017f6f00a
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp101
-rw-r--r--services/surfaceflinger/DisplayDevice.h23
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp46
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
4 files changed, 125 insertions, 47 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 16e5547..cf781d3 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -38,6 +38,7 @@
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"
+#include "clz.h"
#include "DisplayDevice.h"
#include "GLExtensions.h"
#include "SurfaceFlinger.h"
@@ -84,8 +85,8 @@ DisplayDevice::DisplayDevice(
mPageFlipCount(),
mSecureLayerVisible(false),
mScreenAcquired(false),
- mOrientation(),
- mLayerStack(0)
+ mLayerStack(0),
+ mOrientation()
{
init(config);
}
@@ -139,6 +140,8 @@ void DisplayDevice::init(EGLConfig config)
mSurface = surface;
mFormat = format;
mPageFlipCount = 0;
+ mViewport.makeInvalid();
+ mFrame.makeInvalid();
// external displays are always considered enabled
mScreenAcquired = (mType >= DisplayDevice::NUM_DISPLAY_TYPES);
@@ -192,12 +195,23 @@ void DisplayDevice::dump(String8& res) const
}
}
-void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) {
+EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy,
+ const sp<const DisplayDevice>& hw, EGLContext ctx) {
+ EGLBoolean result = EGL_TRUE;
EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
if (sur != hw->mSurface) {
- EGLDisplay dpy = eglGetCurrentDisplay();
- eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
+ result = eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
+ if (result == EGL_TRUE) {
+ GLsizei w = hw->mDisplayWidth;
+ GLsizei h = hw->mDisplayHeight;
+ glViewport(0, 0, w, h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ // put the origin in the left-bottom corner
+ glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
+ }
}
+ return result;
}
// ----------------------------------------------------------------------------
@@ -223,10 +237,10 @@ bool DisplayDevice::getSecureLayerVisible() const {
Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
Region dirty;
- const Transform& planeTransform(mGlobalTransform);
if (repaintEverything) {
dirty.set(getBounds());
} else {
+ const Transform& planeTransform(mGlobalTransform);
dirty = planeTransform.transform(this->dirtyRegion);
dirty.andSelf(getBounds());
}
@@ -284,18 +298,73 @@ status_t DisplayDevice::orientationToTransfrom(
return NO_ERROR;
}
-status_t DisplayDevice::setOrientation(int orientation) {
+void DisplayDevice::setOrientation(int orientation) {
+ mOrientation = orientation;
+ updateGeometryTransform();
+}
+
+void DisplayDevice::setViewport(const Rect& viewport) {
+ if (viewport.isValid()) {
+ mViewport = viewport;
+ updateGeometryTransform();
+ }
+}
+
+void DisplayDevice::setFrame(const Rect& frame) {
+ if (frame.isValid()) {
+ mFrame = frame;
+ updateGeometryTransform();
+ }
+}
+
+void DisplayDevice::updateGeometryTransform() {
int w = mDisplayWidth;
int h = mDisplayHeight;
+ Transform R, S;
+ if (DisplayDevice::orientationToTransfrom(
+ mOrientation, w, h, &R) == NO_ERROR) {
+ dirtyRegion.set(bounds());
+
+ Rect viewport(mViewport);
+ Rect frame(mFrame);
+
+ if (!frame.isValid()) {
+ // the destination frame can be invalid if it has never been set,
+ // in that case we assume the whole display frame.
+ frame = Rect(w, h);
+ }
+
+ if (viewport.isEmpty()) {
+ // viewport can be invalid if it has never been set, in that case
+ // we assume the whole display size.
+ // it's also invalid to have an empty viewport, so we handle that
+ // case in the same way.
+ viewport = Rect(w, h);
+ if (R.getOrientation() & Transform::ROT_90) {
+ // viewport is always specified in the logical orientation
+ // of the display (ie: post-rotation).
+ swap(viewport.right, viewport.bottom);
+ }
+ }
- DisplayDevice::orientationToTransfrom(
- orientation, w, h, &mGlobalTransform);
- if (orientation & DisplayState::eOrientationSwapMask) {
- int tmp = w;
- w = h;
- h = tmp;
+ float src_width = viewport.width();
+ float src_height = viewport.height();
+ float dst_width = frame.width();
+ float dst_height = frame.height();
+ if (src_width != src_height || dst_width != dst_height) {
+ float sx = dst_width / src_width;
+ float sy = dst_height / src_height;
+ S.set(sx, 0, 0, sy);
+ }
+ float src_x = viewport.left;
+ float src_y = viewport.top;
+ float dst_x = frame.left;
+ float dst_y = frame.top;
+ float tx = dst_x - src_x;
+ float ty = dst_y - src_y;
+ S.set(tx, ty);
+
+ // rotate first, followed by scaling
+ mGlobalTransform = S * R;
}
- mOrientation = orientation;
- dirtyRegion.set(bounds());
- return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index b742b13..12a0152 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -93,11 +93,16 @@ public:
bool getSecureLayerVisible() const;
Region getDirtyRegion(bool repaintEverything) const;
- status_t setOrientation(int orientation);
void setLayerStack(uint32_t stack);
+ void setOrientation(int orientation);
+ void setViewport(const Rect& viewport);
+ void setFrame(const Rect& frame);
int getOrientation() const { return mOrientation; }
const Transform& getTransform() const { return mGlobalTransform; }
+ const Rect& getViewport() const { return mViewport; }
+ const Rect& getFrame() const { return mFrame; }
+
uint32_t getLayerStack() const { return mLayerStack; }
int32_t getDisplayType() const { return mType; }
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
@@ -110,7 +115,8 @@ public:
}
inline Rect bounds() const { return getBounds(); }
- static void makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx);
+ static EGLBoolean makeCurrent(EGLDisplay dpy,
+ const sp<const DisplayDevice>& hw, EGLContext ctx);
/* ------------------------------------------------------------------------
* blank / unplank management
@@ -170,11 +176,16 @@ private:
/*
* Transaction state
*/
- static status_t orientationToTransfrom(int orientation, int w, int h,
- Transform* tr);
- Transform mGlobalTransform;
- int mOrientation;
+ static status_t orientationToTransfrom(int orientation,
+ int w, int h, Transform* tr);
+
+ void updateGeometryTransform();
+
uint32_t mLayerStack;
+ int mOrientation;
+ Rect mViewport;
+ Rect mFrame;
+ Transform mGlobalTransform;
};
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ee653f3..ed91d44 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -297,8 +297,8 @@ EGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config)
return ctxt;
}
-void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
- EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
+void SurfaceFlinger::initializeGL(EGLDisplay display, const sp<DisplayDevice>& hw) {
+ EGLBoolean result = DisplayDevice::makeCurrent(display, hw, mEGLContext);
if (!result) {
ALOGE("Couldn't create a working GLES context. check logs. exiting...");
exit(0);
@@ -314,10 +314,6 @@ void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
eglQueryString(display, EGL_VERSION),
eglQueryString(display, EGL_EXTENSIONS));
- EGLint w, h;
- eglQuerySurface(display, surface, EGL_WIDTH, &w);
- eglQuerySurface(display, surface, EGL_HEIGHT, &h);
-
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
@@ -344,12 +340,6 @@ void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // put the origin in the left-bottom corner
- glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
-
// print some debugging info
EGLint r,g,b,a;
eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r);
@@ -412,8 +402,7 @@ status_t SurfaceFlinger::readyToRun()
mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);
// initialize OpenGL ES
- EGLSurface surface = hw->getEGLSurface();
- initializeGL(mEGLDisplay, surface);
+ initializeGL(mEGLDisplay, hw);
// start the EventThread
mEventThread = new EventThread(this);
@@ -863,7 +852,7 @@ void SurfaceFlinger::postFramebuffer()
// FIXME: EGL spec says:
// "surface must be bound to the calling thread's current context,
// for the current rendering API."
- DisplayDevice::makeCurrent(getDefaultDisplayDevice(), mEGLContext);
+ DisplayDevice::makeCurrent(mEGLDisplay, getDefaultDisplayDevice(), mEGLContext);
hwc.commit();
}
@@ -983,11 +972,14 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
if (state.layerStack != draw[i].layerStack) {
disp->setLayerStack(state.layerStack);
}
- if (state.orientation != draw[i].orientation ||
- state.viewport != draw[i].viewport ||
- state.frame != draw[i].frame) {
+ if (state.orientation != draw[i].orientation) {
disp->setOrientation(state.orientation);
- // TODO: take viewport and frame into account
+ }
+ if (state.viewport != draw[i].viewport) {
+ disp->setViewport(state.viewport);
+ }
+ if (state.frame != draw[i].frame) {
+ disp->setFrame(state.frame);
}
}
}
@@ -1006,7 +998,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
state.type, display, stc, 0, mEGLConfig);
disp->setLayerStack(state.layerStack);
disp->setOrientation(state.orientation);
- // TODO: take viewport and frame into account
+ disp->setViewport(state.viewport);
+ disp->setFrame(state.frame);
mDisplays.add(display, disp);
}
}
@@ -1280,7 +1273,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
if (hasGlesComposition) {
- DisplayDevice::makeCurrent(hw, mEGLContext);
+ DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
// set the frame buffer
glMatrixMode(GL_MODELVIEW);
@@ -1977,15 +1970,18 @@ void SurfaceFlinger::dumpAllLocked(
const sp<const DisplayDevice>& hw(mDisplays[dpy]);
snprintf(buffer, SIZE,
"+ DisplayDevice[%u]\n"
- " id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, "
- "flips=%u, secure=%d, numLayers=%u\n",
+ " id=%x, layerStack=%u, (%4dx%4d), orient=%2d (type=%08x), "
+ "flips=%u, secure=%d, numLayers=%u, v:[%d,%d,%d,%d], f:[%d,%d,%d,%d]\n",
dpy,
hw->getDisplayType(), hw->getLayerStack(),
hw->getWidth(), hw->getHeight(),
hw->getOrientation(), hw->getTransform().getType(),
hw->getPageFlipCount(),
hw->getSecureLayerVisible(),
- hw->getVisibleLayersSortedByZ().size());
+ hw->getVisibleLayersSortedByZ().size(),
+ hw->getViewport().left, hw->getViewport().top, hw->getViewport().right, hw->getViewport().bottom,
+ hw->getFrame().left, hw->getFrame().top, hw->getFrame().right, hw->getFrame().bottom);
+
result.append(buffer);
}
@@ -2488,6 +2484,8 @@ SurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
: type(type), layerStack(0), orientation(0) {
+ viewport.makeInvalid();
+ frame.makeInvalid();
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 9db6b2d..ea03e2d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -320,7 +320,7 @@ private:
EGLint const* attrs, PixelFormat format, EGLConfig* outConfig);
static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId);
static EGLContext createGLContext(EGLDisplay disp, EGLConfig config);
- void initializeGL(EGLDisplay display, EGLSurface surface);
+ void initializeGL(EGLDisplay display, const sp<DisplayDevice>& hw);
uint32_t getMaxTextureSize() const;
uint32_t getMaxViewportDims() const;