Implement a new way of transforming source buffers
The code is similar to LayerDrawable::DrawLayer method (frameworks/base/libs/hwui/pipeline/skia/LayerDrawable.cpp), this new implementation solves skia rendering issues from camera app, recent apps, and chrome video layer, etc.
There are still small defects that another CL is needed, tracked by this new bug: b/175141036.
Bug: 172422614
Bug: 172579023
Test: adb root; adb shell setprop debug.renderengine.backend skiagl; adb
shell stop; adb shell start; adb shell service call SurfaceFlinger 1008 i32 1
then open camera app, or drag in recent apps
Change-Id: Ia696add519f6541d21ab7fb81d882daa51353847
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 8dc0c68..be6b081 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -550,8 +550,6 @@
if (layer->source.buffer.buffer) {
ATRACE_NAME("DrawImage");
const auto& item = layer->source.buffer;
- const auto bufferWidth = item.buffer->getBounds().width();
- const auto bufferHeight = item.buffer->getBounds().height();
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr;
auto iter = mTextureCache.find(item.buffer->getId());
if (iter != mTextureCache.end()) {
@@ -583,50 +581,19 @@
? kPremul_SkAlphaType
: kUnpremul_SkAlphaType),
mGrContext.get());
- SkMatrix matrix;
- if (layer->geometry.roundedCornersRadius > 0) {
- const auto roundedRect = getRoundedRect(layer);
- matrix.setTranslate(roundedRect.getBounds().left() - dest.left(),
- roundedRect.getBounds().top() - dest.top());
- } else {
- matrix.setIdentity();
- }
auto texMatrix = getSkM44(item.textureTransform).asM33();
-
- // b/171404534, scale to fix the layer
- matrix.postScale(bounds.getWidth() / bufferWidth, bounds.getHeight() / bufferHeight);
-
// textureTansform was intended to be passed directly into a shader, so when
// building the total matrix with the textureTransform we need to first
// normalize it, then apply the textureTransform, then scale back up.
- matrix.postScale(1.0f / bufferWidth, 1.0f / bufferHeight);
+ texMatrix.preScale(1.0f / bounds.getWidth(), 1.0f / bounds.getHeight());
+ texMatrix.postScale(image->width(), image->height());
- auto rotatedBufferWidth = bufferWidth;
- auto rotatedBufferHeight = bufferHeight;
-
- // Swap the buffer width and height if we're rotating, so that we
- // scale back up by the correct factors post-rotation.
- if (texMatrix.getSkewX() <= -0.5f || texMatrix.getSkewX() >= 0.5f) {
- std::swap(rotatedBufferWidth, rotatedBufferHeight);
- // TODO: clean this up.
- // GLESRenderEngine specifies its texture coordinates in
- // CW orientation under OpenGL conventions, when they probably should have
- // been CCW instead. The net result is that orientation
- // transforms are applied in the reverse
- // direction to render the correct result, because SurfaceFlinger uses the inverse
- // of the display transform to correct for that. But this means that
- // the tex transform passed by SkiaGLRenderEngine will rotate
- // individual layers in the reverse orientation. Hack around it
- // by injected a 180 degree rotation, but ultimately this is
- // a bug in how SurfaceFlinger invokes the RenderEngine
- // interface, so the proper fix should live there, and GLESRenderEngine
- // should be fixed accordingly.
- matrix.postRotate(180, 0.5, 0.5);
+ SkMatrix matrix;
+ if (!texMatrix.invert(&matrix)) {
+ matrix = texMatrix;
}
- matrix.postConcat(texMatrix);
- matrix.postScale(rotatedBufferWidth, rotatedBufferHeight);
sk_sp<SkShader> shader;
if (layer->source.buffer.useTextureFiltering) {