diff options
author | Mathias Agopian <mathias@google.com> | 2010-08-19 17:01:19 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2010-08-24 15:40:50 -0700 |
commit | b661d66013b9803c50dc78ca0247ac39caef443a (patch) | |
tree | 8844bd39ddf6611d60803a015b1861fb8faf0e2b /services/surfaceflinger | |
parent | af2ac558a47d2f69c69755e0ac95b792bd0f1f3b (diff) | |
download | frameworks_native-b661d66013b9803c50dc78ca0247ac39caef443a.zip frameworks_native-b661d66013b9803c50dc78ca0247ac39caef443a.tar.gz frameworks_native-b661d66013b9803c50dc78ca0247ac39caef443a.tar.bz2 |
fix [2931513] Add support for setting the orientation of an ANativeWindow
Also implement support for cropping.
Change-Id: Iba5888dd242bf2feaac9e9ce26e404c1f404c280
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.cpp | 107 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBlur.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBuffer.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/TextureManager.h | 3 |
6 files changed, 102 insertions, 29 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 629d993..6f3c66d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -473,9 +473,9 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) return; } - // get the dirty region sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); if (newFrontBuffer != NULL) { + // get the dirty region // compute the posted region const Region dirty(lcblk->getDirtyRegion(buf)); mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); @@ -511,6 +511,13 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // we now have the correct size, unfreeze the screen mFreezeLock.clear(); } + + // get the crop region + setBufferCrop( lcblk->getCrop(buf) ); + + // get the transformation + setBufferTransform( lcblk->getTransform(buf) ); + } else { // this should not happen unless we ran out of memory while // allocating the buffer. we're hoping that things will get back diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index 91ac915..6fc5010 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -54,6 +54,8 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) { const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); mFlags = hw.getFlags(); + mBufferCrop.makeInvalid(); + mBufferTransform = 0; } LayerBase::~LayerBase() @@ -345,6 +347,14 @@ void LayerBase::clearWithOpenGL(const Region& clip) const clearWithOpenGL(clip,0,0,0,0); } +template <typename T> +static inline +void swap(T& a, T& b) { + T t(a); + a = b; + b = t; +} + void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); @@ -378,38 +388,73 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const } } - Region::const_iterator it = clip.begin(); - Region::const_iterator const end = clip.end(); - const GLfloat texCoords[4][2] = { - { 0, 0 }, - { 0, 1 }, - { 1, 1 }, - { 1, 0 } + /* + * compute texture coordinates + * here, we handle NPOT, cropping and buffer transformations + */ + + GLfloat cl, ct, cr, cb; + if (!mBufferCrop.isEmpty()) { + // source is cropped + const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width; + const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height; + cl = mBufferCrop.left * us; + ct = mBufferCrop.top * vs; + cr = mBufferCrop.right * us; + cb = mBufferCrop.bottom * vs; + } else { + cl = 0; + ct = 0; + cr = (texture.NPOTAdjust ? texture.wScale : 1.0f); + cb = (texture.NPOTAdjust ? texture.hScale : 1.0f); + } + + struct TexCoords { + GLfloat u; + GLfloat v; + }; + + enum { + // name of the corners in the texture map + LB = 0, // left-bottom + LT = 1, // left-top + RT = 2, // right-top + RB = 3 // right-bottom }; - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); + // vertices in screen space + int vLT = LB; + int vLB = LT; + int vRB = RT; + int vRT = RB; // the texture's source is rotated - switch (texture.transform) { - case HAL_TRANSFORM_ROT_90: - glTranslatef(0, 1, 0); - glRotatef(-90, 0, 0, 1); - break; - case HAL_TRANSFORM_ROT_180: - glTranslatef(1, 1, 0); - glRotatef(-180, 0, 0, 1); - break; - case HAL_TRANSFORM_ROT_270: - glTranslatef(1, 0, 0); - glRotatef(-270, 0, 0, 1); - break; + uint32_t transform = mBufferTransform; + if (transform & HAL_TRANSFORM_ROT_90) { + vLT = RB; + vLB = LB; + vRB = LT; + vRT = RT; } - - if (texture.NPOTAdjust) { - glScalef(texture.wScale, texture.hScale, 1.0f); + if (transform & HAL_TRANSFORM_FLIP_V) { + swap(vLT, vLB); + swap(vRB, vRT); + } + if (transform & HAL_TRANSFORM_FLIP_H) { + swap(vLT, vRB); + swap(vLB, vRT); } + TexCoords texCoords[4]; + texCoords[vLT].u = cl; + texCoords[vLT].v = ct; + texCoords[vLB].u = cl; + texCoords[vLB].v = cb; + texCoords[vRB].u = cr; + texCoords[vRB].v = cb; + texCoords[vRT].u = cr; + texCoords[vRT].v = ct; + if (needsDithering()) { glEnable(GL_DITHER); } else { @@ -420,6 +465,8 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + Region::const_iterator it = clip.begin(); + Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); @@ -429,6 +476,16 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glDisableClientState(GL_TEXTURE_COORD_ARRAY); } +void LayerBase::setBufferCrop(const Rect& crop) { + if (!crop.isEmpty()) { + mBufferCrop = crop; + } +} + +void LayerBase::setBufferTransform(uint32_t transform) { + mBufferTransform = transform; +} + void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const { const Layer::State& s(drawingState()); diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 22bf857..8cba287 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -226,9 +226,17 @@ protected: void clearWithOpenGL(const Region& clip) const; void drawWithOpenGL(const Region& clip, const Texture& texture) const; + // these must be called from the post/drawing thread + void setBufferCrop(const Rect& crop); + void setBufferTransform(uint32_t transform); + sp<SurfaceFlinger> mFlinger; uint32_t mFlags; + // post/drawing thread + Rect mBufferCrop; + uint32_t mBufferTransform; + // cached during validateVisibility() bool mNeedsFiltering; int32_t mOrientation; diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp index 64a43c7..2ee21b9 100644 --- a/services/surfaceflinger/LayerBlur.cpp +++ b/services/surfaceflinger/LayerBlur.cpp @@ -241,6 +241,8 @@ void LayerBlur::onDraw(const Region& clip) const glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); } } diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp index 5f83636..0240748 100644 --- a/services/surfaceflinger/LayerBuffer.cpp +++ b/services/surfaceflinger/LayerBuffer.cpp @@ -485,7 +485,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const mTextureManager.loadTexture(&mTexture, dirty, t); } - mTexture.transform = mBufferHeap.transform; + mLayer.setBufferTransform(mBufferHeap.transform); mLayer.drawWithOpenGL(clip, mTexture); } diff --git a/services/surfaceflinger/TextureManager.h b/services/surfaceflinger/TextureManager.h index c7c14e7..18c4348 100644 --- a/services/surfaceflinger/TextureManager.h +++ b/services/surfaceflinger/TextureManager.h @@ -40,12 +40,11 @@ class GraphicBuffer; struct Image { enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 }; Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0), - transform(0), dirty(1), target(TEXTURE_2D) { } + dirty(1), target(TEXTURE_2D) { } GLuint name; EGLImageKHR image; GLuint width; GLuint height; - uint32_t transform; unsigned dirty : 1; unsigned target : 1; }; |