am da8d0a5c
: implement display viewport and frame
* commit 'da8d0a5c0cf9d41915d3b106cad4aaec3e767c11': implement display viewport and frame
This commit is contained in:
commit
84eda0448a
@ -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());
|
||||
|
||||
DisplayDevice::orientationToTransfrom(
|
||||
orientation, w, h, &mGlobalTransform);
|
||||
if (orientation & DisplayState::eOrientationSwapMask) {
|
||||
int tmp = w;
|
||||
w = h;
|
||||
h = tmp;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user