summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/surfaceflinger/Layer.cpp15
-rw-r--r--libs/surfaceflinger/Layer.h2
-rw-r--r--libs/surfaceflinger/LayerBase.cpp56
-rw-r--r--libs/surfaceflinger/LayerBase.h6
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp5
-rw-r--r--libs/surfaceflinger/Transform.h8
6 files changed, 62 insertions, 30 deletions
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 8dfc2cf766..67ddcf9cee 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -51,7 +51,8 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& c, int32_t i)
: LayerBaseClient(flinger, display, c, i),
mSecure(false),
- mNeedsBlending(true)
+ mNeedsBlending(true),
+ mNeedsDithering(false)
{
// no OpenGL operation is possible here, since we might not be
// in the OpenGL thread.
@@ -106,10 +107,16 @@ status_t Layer::ditch()
status_t Layer::setBuffers( uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags)
{
+ // this surfaces pixel format
PixelFormatInfo info;
status_t err = getPixelFormatInfo(format, &info);
if (err) return err;
+ // the display's pixel format
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ PixelFormatInfo displayInfo;
+ getPixelFormatInfo(hw.getFormat(), &displayInfo);
+
uint32_t bufferFlags = 0;
if (flags & ISurfaceComposer::eSecure)
bufferFlags |= Buffer::SECURE;
@@ -119,6 +126,12 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
mHeight = h;
mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+
+ // we use the red index
+ int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
+ int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
+ mNeedsDithering = layerRedsize > displayRedSize;
+
mBufferFlags = bufferFlags;
for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
mBuffers[i] = new Buffer();
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 2e8173d505..6c7b27b205 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -68,6 +68,7 @@ public:
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
virtual void finishPageFlip();
virtual bool needsBlending() const { return mNeedsBlending; }
+ virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool isSecure() const { return mSecure; }
virtual sp<Surface> createSurface() const;
virtual status_t ditch();
@@ -109,6 +110,7 @@ private:
bool mSecure;
int32_t mFrontBufferIndex;
bool mNeedsBlending;
+ bool mNeedsDithering;
Region mPostedDirtyRegion;
sp<FreezeLock> mFreezeLock;
PixelFormat mFormat;
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index e08861d371..5a93b2d461 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -56,6 +56,7 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
: dpy(display), contentDirty(false),
mFlinger(flinger),
mTransformed(false),
+ mUseLinearFiltering(false),
mOrientation(0),
mTransactionFlags(0),
mPremultipliedAlpha(true),
@@ -208,7 +209,19 @@ uint32_t LayerBase::doTransaction(uint32_t flags)
flags |= eVisibleRegion;
this->contentDirty = true;
}
-
+
+ if (temp.sequence != front.sequence) {
+ const bool linearFiltering = mUseLinearFiltering;
+ mUseLinearFiltering = false;
+ if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+ // we may use linear filtering, if the matrix scales us
+ const uint8_t type = temp.transform.getType();
+ if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) {
+ mUseLinearFiltering = true;
+ }
+ }
+ }
+
// Commit the transaction
commitTransaction(flags & eRestartTransaction);
return flags;
@@ -332,13 +345,8 @@ GLuint LayerBase::createTexture() const
glBindTexture(GL_TEXTURE_2D, textureName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- if (mFlags & DisplayHardware::SLOW_CONFIG) {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- } else {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return textureName;
}
@@ -385,14 +393,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
glEnable(GL_TEXTURE_2D);
- // Dithering...
- bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
- if (fast || s.flags & ISurfaceComposer::eLayerDither) {
- glEnable(GL_DITHER);
- } else {
- glDisable(GL_DITHER);
- }
-
if (UNLIKELY(s.alpha < 0xFF)) {
// We have an alpha-modulation. We need to modulate all
// texture components by alpha because we're always using
@@ -434,12 +434,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
Region::const_iterator it = clip.begin();
Region::const_iterator const end = clip.end();
if (it != end) {
- // always use high-quality filtering with fast configurations
- bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
- if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
const GLfixed texCoords[4][2] = {
{ 0, 0 },
{ 0, 0x10000 },
@@ -481,11 +475,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
glScissor(r.left, sy, r.width(), r.height());
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
-
- if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
} else {
@@ -512,6 +501,19 @@ void LayerBase::validateTexture(GLint textureName) const
glBindTexture(GL_TEXTURE_2D, textureName);
// TODO: reload the texture if needed
// this is currently done in loadTexture() below
+ if (mUseLinearFiltering) {
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+
+ if (needsDithering()) {
+ glEnable(GL_DITHER);
+ } else {
+ glDisable(GL_DITHER);
+ }
}
void LayerBase::loadTexture(Texture* texture, GLint textureName,
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 3a52240824..233737db15 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -188,6 +188,11 @@ public:
virtual bool needsBlending() const { return false; }
/**
+ * needsDithering - true if this surface needs dithering
+ */
+ virtual bool needsDithering() const { return false; }
+
+ /**
* transformed -- true is this surface needs a to be transformed
*/
virtual bool transformed() const { return mTransformed; }
@@ -254,6 +259,7 @@ protected:
// cached during validateVisibility()
bool mTransformed;
+ bool mUseLinearFiltering;
int32_t mOrientation;
GLfixed mVertices[4][2];
Rect mTransformedBounds;
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index e87b563489..a0b48d4f2d 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1497,11 +1497,12 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
"+ %s %p\n"
" "
"z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
- "needsBlending=%1d, invalidate=%1d, "
+ "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
"alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
layer->getTypeID(), layer.get(),
s.z, layer->tx(), layer->ty(), s.w, s.h,
- layer->needsBlending(), layer->contentDirty,
+ layer->needsBlending(), layer->needsDithering(),
+ layer->contentDirty,
s.alpha, s.flags,
s.transform[0], s.transform[1],
s.transform[2], s.transform[3]);
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
index 4c4528ecd4..78f5c19601 100644
--- a/libs/surfaceflinger/Transform.h
+++ b/libs/surfaceflinger/Transform.h
@@ -50,6 +50,14 @@ public:
ROT_INVALID = 0x80000000
};
+ enum type_mask {
+ IDENTITY = 0,
+ TRANSLATE = 0x1,
+ SCALE = 0x2,
+ AFFINE = 0x4,
+ PERSPECTIVE = 0x8
+ };
+
bool transformed() const;
int32_t getOrientation() const;
bool preserveRects() const;