diff options
author | liyuqian <liyuqian@google.com> | 2016-06-13 12:26:45 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-13 12:26:45 -0700 |
commit | 6f163d29438cefaaa10c5cd68e3b77c3cb9a6b79 (patch) | |
tree | 73894218e9d648670a04b10a19de6913bee2380f /tools | |
parent | d490708198e7129a85a070d15869aca469deb797 (diff) |
Display JPGs in Viewer with Split Screen and ColorSpaceXform
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2058753002
Review-Url: https://codereview.chromium.org/2058753002
Diffstat (limited to 'tools')
-rw-r--r-- | tools/viewer/ImageSlide.cpp | 58 | ||||
-rw-r--r-- | tools/viewer/ImageSlide.h | 34 | ||||
-rw-r--r-- | tools/viewer/Viewer.cpp | 59 | ||||
-rw-r--r-- | tools/viewer/Viewer.h | 4 | ||||
-rw-r--r-- | tools/viewer/sk_app/android/RasterWindowContext_android.cpp | 4 |
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); } |