diff options
author | Mathias Agopian <mathias@google.com> | 2012-09-04 15:05:38 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2012-09-04 16:59:06 -0700 |
commit | da8d0a5c0cf9d41915d3b106cad4aaec3e767c11 (patch) | |
tree | ff32d3624ef19dcd8677dfab3f1b85a3dd0b2b8b | |
parent | 493db47929cdd805339e453062fef265d8985692 (diff) | |
download | frameworks_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.cpp | 101 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 23 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 46 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
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; |