summaryrefslogtreecommitdiffstats
path: root/libs/gui/SurfaceTexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gui/SurfaceTexture.cpp')
-rw-r--r--libs/gui/SurfaceTexture.cpp43
1 files changed, 37 insertions, 6 deletions
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 3bed959..5c6d71b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -283,11 +283,42 @@ void SurfaceTexture::getTransformMatrix(float mtx[16]) {
sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
float tx, ty, sx, sy;
if (!mCurrentCrop.isEmpty()) {
- tx = float(mCurrentCrop.left) / float(buf->getWidth());
- ty = float(buf->getHeight() - mCurrentCrop.bottom) /
- float(buf->getHeight());
- sx = float(mCurrentCrop.width()) / float(buf->getWidth());
- sy = float(mCurrentCrop.height()) / float(buf->getHeight());
+ // In order to prevent bilinear sampling at the of the crop rectangle we
+ // may need to shrink it by 2 texels in each direction. Normally this
+ // would just need to take 1/2 a texel off each end, but because the
+ // chroma channels will likely be subsampled we need to chop off a whole
+ // texel. This will cause artifacts if someone does nearest sampling
+ // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
+ // accomodate the bilinear and nearest sampling uses.
+ //
+ // If nearest sampling turns out to be a desirable usage of these
+ // textures then we could add the ability to switch a SurfaceTexture to
+ // nearest-mode. Preferably, however, the image producers (video
+ // decoder, camera, etc.) would simply not use a crop rectangle (or at
+ // least not tell the framework about it) so that the GPU can do the
+ // correct edge behavior.
+ int xshrink = 0, yshrink = 0;
+ if (mCurrentCrop.left > 0) {
+ tx = float(mCurrentCrop.left + 1) / float(buf->getWidth());
+ xshrink++;
+ } else {
+ tx = 0.0f;
+ }
+ if (mCurrentCrop.right < buf->getWidth()) {
+ xshrink++;
+ }
+ if (mCurrentCrop.bottom < buf->getHeight()) {
+ ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) /
+ float(buf->getHeight());
+ yshrink++;
+ } else {
+ ty = 0.0f;
+ }
+ if (mCurrentCrop.top > 0) {
+ yshrink++;
+ }
+ sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth());
+ sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight());
} else {
tx = 0.0f;
ty = 0.0f;
@@ -298,7 +329,7 @@ void SurfaceTexture::getTransformMatrix(float mtx[16]) {
sx, 0, 0, 0,
0, sy, 0, 0,
0, 0, 1, 0,
- sx*tx, sy*ty, 0, 1,
+ tx, ty, 0, 1,
};
float mtxBeforeFlipV[16];