Add SkEncodedOrigin to SkYUVASizeInfo, fix JPEG orientation in GPU decode path
Bug: skia:7523
Change-Id: I7d48e5f5930b413fa7f27aa391bf92c5af1342e9
Reviewed-on: https://skia-review.googlesource.com/c/173429
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 77ec70f..ca3ac3b 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -854,6 +854,8 @@
// JPEG never has an alpha channel
sizeInfo->fSizes[3].fHeight = sizeInfo->fSizes[3].fWidth = sizeInfo->fWidthBytes[3] = 0;
+ sizeInfo->fOrigin = this->getOrigin();
+
if (colorSpace) {
*colorSpace = kJPEG_SkYUVColorSpace;
}
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index 8f550f8..316614e 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -434,7 +434,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////////
-static bool draw_orientation(const SkPixmap& dst, const SkPixmap& src, unsigned flags) {
+static bool draw_orientation(const SkPixmap& dst, const SkPixmap& src, SkEncodedOrigin origin) {
auto surf = SkSurface::MakeRasterDirect(dst.info(), dst.writable_addr(), dst.rowBytes());
if (!surf) {
return false;
@@ -443,26 +443,8 @@
SkBitmap bm;
bm.installPixels(src);
- SkMatrix m;
- m.setIdentity();
+ SkMatrix m = SkEncodedOriginToMatrix(origin, src.width(), src.height());
- SkScalar W = SkIntToScalar(src.width());
- SkScalar H = SkIntToScalar(src.height());
- if (flags & SkPixmapPriv::kSwapXY) {
- SkMatrix s;
- s.setAll(0, 1, 0, 1, 0, 0, 0, 0, 1);
- m.postConcat(s);
- using std::swap;
- swap(W, H);
- }
- if (flags & SkPixmapPriv::kMirrorX) {
- m.postScale(-1, 1);
- m.postTranslate(W, 0);
- }
- if (flags & SkPixmapPriv::kMirrorY) {
- m.postScale(1, -1);
- m.postTranslate(0, H);
- }
SkPaint p;
p.setBlendMode(SkBlendMode::kSrc);
surf->getCanvas()->concat(m);
@@ -470,8 +452,7 @@
return true;
}
-bool SkPixmapPriv::Orient(const SkPixmap& dst, const SkPixmap& src, OrientFlags flags) {
- SkASSERT((flags & ~(kMirrorX | kMirrorY | kSwapXY)) == 0);
+bool SkPixmapPriv::Orient(const SkPixmap& dst, const SkPixmap& src, SkEncodedOrigin origin) {
if (src.colorType() != dst.colorType()) {
return false;
}
@@ -479,7 +460,7 @@
int w = src.width();
int h = src.height();
- if (flags & kSwapXY) {
+ if (ShouldSwapWidthHeight(origin)) {
using std::swap;
swap(w, h);
}
@@ -492,34 +473,14 @@
// check for aliasing to self
if (src.addr() == dst.addr()) {
- return flags == 0;
+ return kTopLeft_SkEncodedOrigin == origin;
}
- return draw_orientation(dst, src, flags);
+ return draw_orientation(dst, src, origin);
}
-#define kMirrorX SkPixmapPriv::kMirrorX
-#define kMirrorY SkPixmapPriv::kMirrorY
-#define kSwapXY SkPixmapPriv::kSwapXY
-
-static constexpr uint8_t gOrientationFlags[] = {
- 0, // kTopLeft_SkEncodedOrigin
- kMirrorX, // kTopRight_SkEncodedOrigin
- kMirrorX | kMirrorY, // kBottomRight_SkEncodedOrigin
- kMirrorY, // kBottomLeft_SkEncodedOrigin
- kSwapXY, // kLeftTop_SkEncodedOrigin
- kMirrorX | kSwapXY, // kRightTop_SkEncodedOrigin
- kMirrorX | kMirrorY | kSwapXY, // kRightBottom_SkEncodedOrigin
- kMirrorY | kSwapXY, // kLeftBottom_SkEncodedOrigin
-};
-
-SkPixmapPriv::OrientFlags SkPixmapPriv::OriginToOrient(SkEncodedOrigin o) {
- unsigned io = static_cast<int>(o) - 1;
- SkASSERT(io < SK_ARRAY_COUNT(gOrientationFlags));
- return static_cast<SkPixmapPriv::OrientFlags>(gOrientationFlags[io]);
-}
-
-bool SkPixmapPriv::ShouldSwapWidthHeight(SkEncodedOrigin o) {
- return SkToBool(OriginToOrient(o) & kSwapXY);
+bool SkPixmapPriv::ShouldSwapWidthHeight(SkEncodedOrigin origin) {
+ // The last four SkEncodedOrigin values involve 90 degree rotations
+ return origin >= kLeftTop_SkEncodedOrigin;
}
SkImageInfo SkPixmapPriv::SwapWidthHeight(const SkImageInfo& info) {
diff --git a/src/core/SkPixmapPriv.h b/src/core/SkPixmapPriv.h
index cced3e2..4f3b3b5 100644
--- a/src/core/SkPixmapPriv.h
+++ b/src/core/SkPixmapPriv.h
@@ -14,20 +14,11 @@
class SkPixmapPriv {
public:
- // These flag are applied in this order (swap is applied last)
- enum OrientFlags {
- kMirrorX = 1 << 0,
- kMirrorY = 1 << 1,
- kSwapXY = 1 << 2,
- };
-
- static OrientFlags OriginToOrient(SkEncodedOrigin);
-
/**
* Copy the pixels in this pixmap into dst, applying the orientation transformations specified
* by the flags. If the inputs are invalid, this returns false and no copy is made.
*/
- static bool Orient(const SkPixmap& dst, const SkPixmap& src, OrientFlags);
+ static bool Orient(const SkPixmap& dst, const SkPixmap& src, SkEncodedOrigin);
static bool ShouldSwapWidthHeight(SkEncodedOrigin o);
static SkImageInfo SwapWidthHeight(const SkImageInfo& info);
@@ -59,7 +50,7 @@
return false;
}
if (tmp != &dst) {
- return Orient(dst, *tmp, OriginToOrient(origin));
+ return Orient(dst, *tmp, origin);
}
return true;
}
@@ -71,4 +62,3 @@
};
#endif
-
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 16027df..6b3eb88 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -182,7 +182,8 @@
const SkRect r = SkRect::MakeIWH(yuvSizeInfo.fSizes[0].fWidth,
yuvSizeInfo.fSizes[0].fHeight);
- renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), r);
+ SkMatrix m = SkEncodedOriginToMatrix(yuvSizeInfo.fOrigin, r.width(), r.height());
+ renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, m, r);
return renderTargetContext->asTextureProxyRef();
}