aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar liyuqian <liyuqian@google.com>2016-06-13 12:26:45 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-13 12:26:45 -0700
commit6f163d29438cefaaa10c5cd68e3b77c3cb9a6b79 (patch)
tree73894218e9d648670a04b10a19de6913bee2380f /tools
parentd490708198e7129a85a070d15869aca469deb797 (diff)
Display JPGs in Viewer with Split Screen and ColorSpaceXform
Diffstat (limited to 'tools')
-rw-r--r--tools/viewer/ImageSlide.cpp58
-rw-r--r--tools/viewer/ImageSlide.h34
-rw-r--r--tools/viewer/Viewer.cpp59
-rw-r--r--tools/viewer/Viewer.h4
-rw-r--r--tools/viewer/sk_app/android/RasterWindowContext_android.cpp4
5 files changed, 154 insertions, 5 deletions
diff --git a/tools/viewer/ImageSlide.cpp b/tools/viewer/ImageSlide.cpp
new file mode 100644
index 0000000000..4a03185733
--- /dev/null
+++ b/tools/viewer/ImageSlide.cpp
@@ -0,0 +1,58 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "ImageSlide.h"
+
+#include "SkBitmap.h"
+#include "SkCodec.h"
+#include "SkColorSpaceXform.h"
+#include "SkColorSpace.h"
+#include "SkCanvas.h"
+#include "SkData.h"
+#include "SkImage.h"
+#include "SkMetaData.h"
+
+ImageSlide::ImageSlide(const SkString& name, const SkString& path) : fPath(path) {
+ fName = name;
+}
+
+SkISize ImageSlide::getDimensions() const {
+ return fImage ? fImage->dimensions() : SkISize::Make(0, 0);
+}
+
+void ImageSlide::draw(SkCanvas* canvas) {
+ if (canvas->getMetaData().hasBool(kImageColorXformMetaData, true)) {
+ canvas->drawBitmap(fXformedBitmap, 0, 0);
+ } else {
+ // skbug.com/5428
+ // drawImage() and drawBitmap() behave differently in sRGB mode.
+ // canvas->drawImage(fImage.get(), 0, 0);
+ canvas->drawBitmap(fOriginalBitmap, 0, 0);
+ }
+}
+
+void ImageSlide::load() {
+ sk_sp<SkData> encoded = SkData::MakeFromFileName(fPath.c_str());
+ fImage = SkImage::MakeFromEncoded(encoded);
+ fImage->asLegacyBitmap(&fOriginalBitmap, SkImage::kRO_LegacyBitmapMode);
+
+ SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded.get()));
+ sk_sp<SkColorSpace> srcSpace = sk_ref_sp(codec->getColorSpace());
+ sk_sp<SkColorSpace> dstSpace = SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named);
+ std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(srcSpace, dstSpace);
+ fOriginalBitmap.deepCopyTo(&fXformedBitmap);
+ uint32_t* row = (uint32_t*) fXformedBitmap.getPixels();
+ for (int y = 0; y < fXformedBitmap.height(); y++) {
+ xform->xform_RGBA_8888(row, row, fXformedBitmap.width());
+ row = SkTAddOffset<uint32_t>(row, fXformedBitmap.rowBytes());
+ }
+ fXformedBitmap.notifyPixelsChanged(); // This is needed for the deepCopy
+}
+
+void ImageSlide::unload() {
+ fImage.reset(nullptr);
+}
diff --git a/tools/viewer/ImageSlide.h b/tools/viewer/ImageSlide.h
new file mode 100644
index 0000000000..88254ddc03
--- /dev/null
+++ b/tools/viewer/ImageSlide.h
@@ -0,0 +1,34 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef ImageSlide_DEFINED
+#define ImageSlide_DEFINED
+
+#include "Slide.h"
+#include "SkPicture.h"
+#include "SkImage.h"
+
+static const char* kImageColorXformMetaData = "ImageColorSpaceXform";
+
+class ImageSlide : public Slide {
+public:
+ ImageSlide(const SkString& name, const SkString& path);
+
+ SkISize getDimensions() const override;
+
+ void draw(SkCanvas* canvas) override;
+ void load() override;
+ void unload() override;
+
+private:
+ SkString fPath;
+ sk_sp<const SkImage> fImage;
+ SkBitmap fOriginalBitmap;
+ SkBitmap fXformedBitmap;
+};
+
+#endif
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 499673572b..465a7aad4d 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -8,10 +8,12 @@
#include "Viewer.h"
#include "GMSlide.h"
+#include "ImageSlide.h"
#include "SKPSlide.h"
#include "SkCanvas.h"
#include "SkCommonFlags.h"
+#include "SkMetaData.h"
#include "SkOSFile.h"
#include "SkRandom.h"
#include "SkStream.h"
@@ -52,10 +54,13 @@ DEFINE_string2(match, m, nullptr,
"^ and $ requires an exact match\n"
"If a bench does not match any list entry,\n"
"it is skipped unless some list entry starts with ~");
-DEFINE_string(skps, "skps", "Directory to read skps from.");
#ifdef SK_BUILD_FOR_ANDROID
+DEFINE_string(skps, "/data/local/tmp/skia", "Directory to read skps from.");
+DEFINE_string(jpgs, "/data/local/tmp/skia", "Directory to read jpgs from.");
DEFINE_bool(vulkan, false, "Run with Vulkan.");
#else
+DEFINE_string(skps, "skps", "Directory to read skps from.");
+DEFINE_string(jpgs, "jpgs", "Directory to read jpgs from.");
DEFINE_bool(vulkan, true, "Run with Vulkan.");
#endif
@@ -73,10 +78,14 @@ const char* kBackendStateName = "Backend";
const char* kSoftkeyStateName = "Softkey";
const char* kSoftkeyHint = "Please select a softkey";
const char* kFpsStateName = "FPS";
+const char* kSplitScreenStateName = "Split screen";
+const char* kON = "ON";
+const char* kOFF = "OFF";
Viewer::Viewer(int argc, char** argv, void* platformData)
: fCurrentMeasurement(0)
, fDisplayStats(false)
+ , fSplitScreen(false)
, fBackendType(sk_app::Window::kVulkan_BackendType)
, fZoomCenterX(0.0f)
, fZoomCenterY(0.0f)
@@ -224,6 +233,19 @@ void Viewer::initSlides() {
}
}
}
+
+ // JPGs
+ for (int i = 0; i < FLAGS_jpgs.count(); i++) {
+ SkOSFile::Iter it(FLAGS_jpgs[i], ".jpg");
+ SkString jpgName;
+ while (it.next(&jpgName)) {
+ SkString path = SkOSPath::Join(FLAGS_jpgs[i], jpgName.c_str());
+ sk_sp<ImageSlide> slide(new ImageSlide(jpgName, path));
+ if (slide) {
+ fSlides.push_back(slide);
+ }
+ }
+ }
}
@@ -247,6 +269,9 @@ void Viewer::setupCurrentSlide(int previousSlide) {
return; // no change; do nothing
}
+ // prepare dimensions for image slides
+ fSlides[fCurrentSlide]->load();
+
fGesture.reset();
fDefaultMatrix.reset();
fDefaultMatrixInv.reset();
@@ -272,7 +297,6 @@ void Viewer::setupCurrentSlide(int previousSlide) {
this->updateTitle();
this->updateUIState();
- fSlides[fCurrentSlide]->load();
if (previousSlide >= 0) {
fSlides[previousSlide]->unload();
}
@@ -317,11 +341,16 @@ SkMatrix Viewer::computeMatrix() {
return m;
}
-void Viewer::onPaint(SkCanvas* canvas) {
+void Viewer::drawSlide(SkCanvas* canvas, bool inSplitScreen) {
+ SkASSERT(!inSplitScreen || fWindow->supportsContentRect());
+
int count = canvas->save();
if (fWindow->supportsContentRect()) {
SkRect contentRect = fWindow->getContentRect();
+ // If inSplitScreen, translate the image half screen to the right.
+ // Thus we have two copies of the image on each half of the screen.
+ contentRect.fLeft += inSplitScreen ? (contentRect.fRight - contentRect.fLeft) * 0.5 : 0;
canvas->clipRect(contentRect);
canvas->translate(contentRect.fLeft, contentRect.fTop);
}
@@ -330,8 +359,16 @@ void Viewer::onPaint(SkCanvas* canvas) {
canvas->concat(fDefaultMatrix);
canvas->concat(computeMatrix());
+ canvas->getMetaData().setBool(kImageColorXformMetaData, inSplitScreen);
fSlides[fCurrentSlide]->draw(canvas);
canvas->restoreToCount(count);
+}
+
+void Viewer::onPaint(SkCanvas* canvas) {
+ drawSlide(canvas, false);
+ if (fSplitScreen && fWindow->supportsContentRect()) {
+ drawSlide(canvas, true);
+ }
if (fDisplayStats) {
drawStats(canvas);
@@ -461,11 +498,20 @@ void Viewer::updateUIState() {
fpsState[kValue] = SkStringPrintf("%8.3lf ms", measurement).c_str();
fpsState[kOptions] = Json::Value(Json::arrayValue);
+ // Split screen state
+ Json::Value splitScreenState(Json::objectValue);
+ splitScreenState[kName] = kSplitScreenStateName;
+ splitScreenState[kValue] = fSplitScreen ? kON : kOFF;
+ splitScreenState[kOptions] = Json::Value(Json::arrayValue);
+ splitScreenState[kOptions].append(kON);
+ splitScreenState[kOptions].append(kOFF);
+
Json::Value state(Json::arrayValue);
state.append(slideState);
state.append(backendState);
state.append(softkeyState);
state.append(fpsState);
+ state.append(splitScreenState);
fWindow->setUIState(state);
}
@@ -508,6 +554,13 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa
fCommands.onSoftkey(stateValue);
updateUIState(); // This is still needed to reset the value to kSoftkeyHint
}
+ } else if (stateName.equals(kSplitScreenStateName)) {
+ bool newSplitScreen = stateValue.equals(kON);
+ if (newSplitScreen != fSplitScreen) {
+ fSplitScreen = newSplitScreen;
+ fWindow->inval();
+ updateUIState();
+ }
} else {
SkDebugf("Unknown stateName: %s", stateName.c_str());
}
diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h
index af3b6ce88d..e140e1b87a 100644
--- a/tools/viewer/Viewer.h
+++ b/tools/viewer/Viewer.h
@@ -35,6 +35,7 @@ private:
void updateUIState();
+ void drawSlide(SkCanvas* canvs, bool inSplitScreen);
void drawStats(SkCanvas* canvas);
void changeZoomLevel(float delta);
@@ -52,6 +53,9 @@ private:
bool fDisplayStats;
+ // whether to split the screen and draw two copies of the slide, one with sRGB and one without
+ bool fSplitScreen;
+
sk_app::Window::BackendType fBackendType;
// transform data
diff --git a/tools/viewer/sk_app/android/RasterWindowContext_android.cpp b/tools/viewer/sk_app/android/RasterWindowContext_android.cpp
index 3ba564635e..5e1e351b9a 100644
--- a/tools/viewer/sk_app/android/RasterWindowContext_android.cpp
+++ b/tools/viewer/sk_app/android/RasterWindowContext_android.cpp
@@ -36,7 +36,7 @@ RasterWindowContext_android::RasterWindowContext_android(
}
void RasterWindowContext_android::setBuffersGeometry() {
- int32_t format;
+ int32_t format = 0;
switch(fDisplayParams.fColorType) {
case kRGBA_8888_SkColorType:
format = WINDOW_FORMAT_RGBA_8888;
@@ -45,7 +45,7 @@ void RasterWindowContext_android::setBuffersGeometry() {
format = WINDOW_FORMAT_RGB_565;
break;
default:
- SkDEBUGFAIL("Unsupported Android color type");
+ SK_ABORT("Unsupported Android color type");
}
ANativeWindow_setBuffersGeometry(fNativeWindow, fWidth, fHeight, format);
}