diff options
Diffstat (limited to 'libs/hwui/pipeline/skia/LayerDrawable.cpp')
-rw-r--r-- | libs/hwui/pipeline/skia/LayerDrawable.cpp | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index 4feeb2d6facb..d9584db2df9d 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#include "GlLayer.h" #include "LayerDrawable.h" +#include "GlLayer.h" #include "VkLayer.h" #include "GrBackendSurface.h" @@ -28,29 +28,32 @@ namespace uirenderer { namespace skiapipeline { void LayerDrawable::onDraw(SkCanvas* canvas) { - DrawLayer(canvas->getGrContext(), canvas, mLayer.get()); + Layer* layer = mLayerUpdater->backingLayer(); + if (layer) { + DrawLayer(canvas->getGrContext(), canvas, layer); + } } bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer) { - // transform the matrix based on the layer - int saveCount = -1; - if (!layer->getTransform().isIdentity()) { - saveCount = canvas->save(); - SkMatrix transform; - layer->getTransform().copyTo(transform); - canvas->concat(transform); + if (context == nullptr) { + SkDEBUGF(("Attempting to draw LayerDrawable into an unsupported surface")); + return false; } - + // transform the matrix based on the layer + SkMatrix layerTransform; + layer->getTransform().copyTo(layerTransform); sk_sp<SkImage> layerImage; + int layerWidth = layer->getWidth(); + int layerHeight = layer->getHeight(); if (layer->getApi() == Layer::Api::OpenGL) { GlLayer* glLayer = static_cast<GlLayer*>(layer); GrGLTextureInfo externalTexture; externalTexture.fTarget = glLayer->getRenderTarget(); externalTexture.fID = glLayer->getTextureId(); - GrBackendTexture backendTexture(glLayer->getWidth(), glLayer->getHeight(), - kRGBA_8888_GrPixelConfig, externalTexture); + GrBackendTexture backendTexture(layerWidth, layerHeight, kRGBA_8888_GrPixelConfig, + externalTexture); layerImage = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin, - kPremul_SkAlphaType, nullptr); + kPremul_SkAlphaType, nullptr); } else { SkASSERT(layer->getApi() == Layer::Api::Vulkan); VkLayer* vkLayer = static_cast<VkLayer*>(layer); @@ -59,20 +62,42 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer } if (layerImage) { + SkMatrix textureMatrix; + layer->getTexTransform().copyTo(textureMatrix); + // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed + // use bottom left origin and remove flipV and invert transformations. + SkMatrix flipV; + flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1); + textureMatrix.preConcat(flipV); + textureMatrix.preScale(1.0f / layerWidth, 1.0f / layerHeight); + textureMatrix.postScale(layerWidth, layerHeight); + SkMatrix textureMatrixInv; + if (!textureMatrix.invert(&textureMatrixInv)) { + textureMatrixInv = textureMatrix; + } + + SkMatrix matrix = SkMatrix::Concat(layerTransform, textureMatrixInv); + SkPaint paint; paint.setAlpha(layer->getAlpha()); paint.setBlendMode(layer->getMode()); paint.setColorFilter(sk_ref_sp(layer->getColorFilter())); - canvas->drawImage(layerImage, 0, 0, &paint); - } - // restore the original matrix - if (saveCount >= 0) { - canvas->restoreToCount(saveCount); + + const bool nonIdentityMatrix = !matrix.isIdentity(); + if (nonIdentityMatrix) { + canvas->save(); + canvas->concat(matrix); + } + canvas->drawImage(layerImage.get(), 0, 0, &paint); + // restore the original matrix + if (nonIdentityMatrix) { + canvas->restore(); + } } return layerImage; } -}; // namespace skiapipeline -}; // namespace uirenderer -}; // namespace android +}; // namespace skiapipeline +}; // namespace uirenderer +}; // namespace android |