-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
@matanlurey and I were investigating a case where SurfaceTexutres appeared to not work on the Impeller GLES backend. Upon investigation we found that they were working, but were only displaying a single pixel.
Consider the following code that is used to draw the external textures:
// The incoming texture is vertically flipped, so we flip it
// back. OpenGL's coordinate system has Positive Y equivalent to up, while
// Skia's coordinate system has Negative Y equvalent to up.
context.canvas->Translate(bounds.x(), bounds.y() + bounds.height());
context.canvas->Scale(bounds.width(), -bounds.height());
if (!transform.isIdentity()) {
DlImageColorSource source(dlimage, DlTileMode::kRepeat,
DlTileMode::kRepeat, sampling, &transform_);
DlPaint paintWithShader;
if (context.paint) {
paintWithShader = *context.paint;
}
paintWithShader.setColorSource(&source);
context.canvas->DrawRect(SkRect::MakeWH(1, 1), paintWithShader);Notice that we draw a 1x1 rectangle and place the scaling transform on the canvas (the entity transform). Separately, the transform applied to the DlImageColorSource (the effect transform) includes a further transformation (maybe the flip?).
When we compute the texture coordinates in impeller, we only apply the effect transform to the rect:
auto uv_transform =
texture_coverage.GetNormalizingTransform() * effect_transform;
std::vector<Point> data(8);
auto points = source_rect.GetPoints();
for (auto i = 0u, j = 0u; i < 8; i += 2, j++) {
data[i] = points[j];
data[i + 1] = uv_transform * points[j];
}
The entity transform is only used as the mvp transform for the vertex_shader coordinates and is not involved in the UV computation.