Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: samplecode/SampleApp.cpp

Issue 2381913003: Support monitor profile in SampleApp (on Windows) (Closed)
Patch Set: Spelling Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « samplecode/SampleApp.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SampleApp.h" 8 #include "SampleApp.h"
9 9
10 #include "OverView.h" 10 #include "OverView.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 # include "gl/GrGLUtil.h" 42 # include "gl/GrGLUtil.h"
43 # include "GrContext.h" 43 # include "GrContext.h"
44 # include "SkGr.h" 44 # include "SkGr.h"
45 # if SK_ANGLE 45 # if SK_ANGLE
46 # include "gl/angle/GLTestContext_angle.h" 46 # include "gl/angle/GLTestContext_angle.h"
47 # endif 47 # endif
48 #else 48 #else
49 class GrContext; 49 class GrContext;
50 #endif 50 #endif
51 51
52 enum OutputColorSpace {
53 kLegacy_OutputColorSpace,
54 kSRGB_OutputColorSpace,
55 kMonitor_OutputColorSpace,
56 };
57
52 const struct { 58 const struct {
53 SkColorType fColorType; 59 SkColorType fColorType;
54 bool fSRGB; 60 OutputColorSpace fColorSpace;
55 const char* fName; 61 const char* fName;
56 } gConfig[] = { 62 } gConfig[] = {
57 { kN32_SkColorType, false, "L32" }, 63 { kN32_SkColorType, kLegacy_OutputColorSpace, "L32" },
58 { kN32_SkColorType, true, "S32" }, 64 { kN32_SkColorType, kSRGB_OutputColorSpace, "S32" },
59 { kRGBA_F16_SkColorType, true, "F16" }, 65 { kRGBA_F16_SkColorType, kSRGB_OutputColorSpace, "F16" },
66 { kRGBA_F16_SkColorType, kMonitor_OutputColorSpace, "F16 Device" },
60 }; 67 };
61 68
62 static const char* find_config_name(const SkImageInfo& info) {
63 for (const auto& config : gConfig) {
64 if (config.fColorType == info.colorType() &&
65 config.fSRGB == (info.colorSpace() != nullptr)) {
66 return config.fName;
67 }
68 }
69 return "???";
70 }
71
72 // Should be 3x + 1 69 // Should be 3x + 1
73 #define kMaxFatBitsScale 28 70 #define kMaxFatBitsScale 28
74 71
75 extern SampleView* CreateSamplePictFileView(const char filename[]); 72 extern SampleView* CreateSamplePictFileView(const char filename[]);
76 73
77 class PictFileFactory : public SkViewFactory { 74 class PictFileFactory : public SkViewFactory {
78 SkString fFilename; 75 SkString fFilename;
79 public: 76 public:
80 PictFileFactory(const SkString& filename) : fFilename(filename) {} 77 PictFileFactory(const SkString& filename) : fFilename(filename) {}
81 SkView* operator() () const override { 78 SkView* operator() () const override {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 return nullptr; 312 return nullptr;
316 } 313 }
317 314
318 void publishCanvas(SampleWindow::DeviceType dType, 315 void publishCanvas(SampleWindow::DeviceType dType,
319 SkCanvas* renderingCanvas, SampleWindow* win) override { 316 SkCanvas* renderingCanvas, SampleWindow* win) override {
320 #if SK_SUPPORT_GPU 317 #if SK_SUPPORT_GPU
321 if (!IsGpuDeviceType(dType) || 318 if (!IsGpuDeviceType(dType) ||
322 kRGBA_F16_SkColorType == win->info().colorType() || 319 kRGBA_F16_SkColorType == win->info().colorType() ||
323 fActualColorBits > 24) { 320 fActualColorBits > 24) {
324 // We made/have an off-screen surface. Get the contents as an SkImag e: 321 // We made/have an off-screen surface. Get the contents as an SkImag e:
322 SkImageInfo offscreenInfo = win->info();
323 if (kMonitor_OutputColorSpace == gConfig[win->getColorConfigIndex()] .fColorSpace) {
324 // This is a big hack. We want our final output to be color "cor rect". If we snap
325 // an image in the gamut of the monitor, and then render to FBO0 (which we've tagged
326 // as sRGB), then we end up doing round-trip gamut conversion, a nd still seeing the
327 // same colors on-screen as if we weren't color managed at all.
328 // Instead, we readPixels into a buffer that we claim is sRGB (r eadPixels doesn't
329 // do gamut conversion), so these pixels then get thrown directl y at the monitor,
330 // giving us the expected results (the output is adapted to the monitor's gamut).
331 auto srgb = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
332 offscreenInfo = offscreenInfo.makeColorSpace(srgb);
333 }
325 SkBitmap bm; 334 SkBitmap bm;
326 bm.allocPixels(win->info()); 335 bm.allocPixels(offscreenInfo);
327 renderingCanvas->readPixels(&bm, 0, 0); 336 renderingCanvas->readPixels(&bm, 0, 0);
328 SkPixmap pm; 337 SkPixmap pm;
329 bm.peekPixels(&pm); 338 bm.peekPixels(&pm);
330 sk_sp<SkImage> image(SkImage::MakeTextureFromPixmap(fCurContext, pm, 339 sk_sp<SkImage> image(SkImage::MakeTextureFromPixmap(fCurContext, pm,
331 SkBudgeted::kNo) ); 340 SkBudgeted::kNo) );
332 341
333 SkCanvas* gpuCanvas = fGpuSurface->getCanvas(); 342 SkCanvas* gpuCanvas = fGpuSurface->getCanvas();
334 343
335 // With ten-bit output, we need to manually apply the gamma of the o utput device 344 // With ten-bit output, we need to manually apply the gamma of the o utput device
336 // (unless we're in non-gamma correct mode, in which case our data i s already 345 // (unless we're in non-gamma correct mode, in which case our data i s already
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 if (!FLAGS_slide.isEmpty()) { 817 if (!FLAGS_slide.isEmpty()) {
809 fCurrIndex = findByTitle(FLAGS_slide[0]); 818 fCurrIndex = findByTitle(FLAGS_slide[0]);
810 if (fCurrIndex < 0) { 819 if (fCurrIndex < 0) {
811 fprintf(stderr, "Unknown sample \"%s\"\n", FLAGS_slide[0]); 820 fprintf(stderr, "Unknown sample \"%s\"\n", FLAGS_slide[0]);
812 listTitles(); 821 listTitles();
813 } 822 }
814 } 823 }
815 824
816 fMSAASampleCount = FLAGS_msaa; 825 fMSAASampleCount = FLAGS_msaa;
817 fDeepColor = FLAGS_deepColor; 826 fDeepColor = FLAGS_deepColor;
827 fColorConfigIndex = 0;
818 828
819 if (FLAGS_list) { 829 if (FLAGS_list) {
820 listTitles(); 830 listTitles();
821 } 831 }
822 832
823 if (fCurrIndex < 0) { 833 if (fCurrIndex < 0) {
824 SkString title; 834 SkString title;
825 if (readTitleFromPrefs(&title)) { 835 if (readTitleFromPrefs(&title)) {
826 fCurrIndex = findByTitle(title.c_str()); 836 fCurrIndex = findByTitle(title.c_str());
827 } 837 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 fPipeSerializer.setTypefaceSerializer(new SampleTFSerializer); 895 fPipeSerializer.setTypefaceSerializer(new SampleTFSerializer);
886 fPipeDeserializer.setTypefaceDeserializer(new SampleTFDeserializer); 896 fPipeDeserializer.setTypefaceDeserializer(new SampleTFDeserializer);
887 } 897 }
888 898
889 int sinkID = this->getSinkID(); 899 int sinkID = this->getSinkID();
890 fAppMenu = new SkOSMenu; 900 fAppMenu = new SkOSMenu;
891 fAppMenu->setTitle("Global Settings"); 901 fAppMenu->setTitle("Global Settings");
892 int itemID; 902 int itemID;
893 903
894 itemID = fAppMenu->appendList("ColorType", "ColorType", sinkID, 0, 904 itemID = fAppMenu->appendList("ColorType", "ColorType", sinkID, 0,
895 gConfig[0].fName, gConfig[1].fName, gConfig[2] .fName, nullptr); 905 gConfig[0].fName,
906 gConfig[1].fName,
907 gConfig[2].fName,
908 gConfig[3].fName,
909 nullptr);
896 fAppMenu->assignKeyEquivalentToItem(itemID, 'C'); 910 fAppMenu->assignKeyEquivalentToItem(itemID, 'C');
897 911
898 itemID = fAppMenu->appendList("Device Type", "Device Type", sinkID, 0, 912 itemID = fAppMenu->appendList("Device Type", "Device Type", sinkID, 0,
899 "Raster", 913 "Raster",
900 "OpenGL", 914 "OpenGL",
901 #if SK_ANGLE 915 #if SK_ANGLE
902 "ANGLE", 916 "ANGLE",
903 #endif 917 #endif
904 nullptr); 918 nullptr);
905 fAppMenu->assignKeyEquivalentToItem(itemID, 'd'); 919 fAppMenu->assignKeyEquivalentToItem(itemID, 'd');
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 void SampleWindow::showOverview() { 1573 void SampleWindow::showOverview() {
1560 this->loadView(create_overview(fSamples.count(), fSamples.begin())); 1574 this->loadView(create_overview(fSamples.count(), fSamples.begin()));
1561 } 1575 }
1562 1576
1563 void SampleWindow::postAnimatingEvent() { 1577 void SampleWindow::postAnimatingEvent() {
1564 if (fAnimating) { 1578 if (fAnimating) {
1565 (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATI NG_DELAY); 1579 (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATI NG_DELAY);
1566 } 1580 }
1567 } 1581 }
1568 1582
1583 static sk_sp<SkColorSpace> getMonitorColorSpace() {
1584 #if defined(SK_BUILD_FOR_MAC)
1585 CGColorSpaceRef cs = CGDisplayCopyColorSpace(CGMainDisplayID());
1586 CFDataRef dataRef = CGColorSpaceCopyICCProfile(cs);
1587 const uint8_t* data = CFDataGetBytePtr(dataRef);
1588 size_t size = CFDataGetLength(dataRef);
1589
1590 sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewICC(data, size);
1591
1592 CFRelease(cs);
1593 CFRelease(dataRef);
1594 return colorSpace;
1595 #elif defined(SK_BUILD_FOR_WIN)
1596 DISPLAY_DEVICE dd = { sizeof(DISPLAY_DEVICE) };
1597
1598 // Chrome's code for this currently just gets the primary monitor's profile. This code iterates
1599 // over all attached monitors, so it's "better" in that sense. Making intell igent use of this
1600 // information (via things like MonitorFromWindow or MonitorFromRect to pick the correct
1601 // profile for a particular window or region of a window), is an exercise le ft to the reader.
1602 for (int i = 0; EnumDisplayDevices(NULL, i, &dd, 0); ++i) {
1603 if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
1604 // There are other helpful things in dd at this point:
1605 // dd.DeviceString has a longer name for the adapter
1606 // dd.StateFlags indicates primary display, mirroring, etc...
1607 HDC dc = CreateDC(NULL, dd.DeviceName, NULL, NULL);
1608 if (dc) {
1609 char icmPath[MAX_PATH + 1];
1610 DWORD pathLength = MAX_PATH;
1611 BOOL success = GetICMProfile(dc, &pathLength, icmPath);
1612 DeleteDC(dc);
1613 if (success) {
1614 sk_sp<SkData> iccData = SkData::MakeFromFileName(icmPath);
1615 return SkColorSpace::NewICC(iccData->data(), iccData->size() );
1616 }
1617 }
1618 }
1619 }
1620
1621 return nullptr;
1622 #else
1623 return nullptr;
1624 #endif
1625 }
1626
1569 bool SampleWindow::onEvent(const SkEvent& evt) { 1627 bool SampleWindow::onEvent(const SkEvent& evt) {
1570 if (evt.isType(gUpdateWindowTitleEvtName)) { 1628 if (evt.isType(gUpdateWindowTitleEvtName)) {
1571 this->updateTitle(); 1629 this->updateTitle();
1572 return true; 1630 return true;
1573 } 1631 }
1574 if (evt.isType(ANIMATING_EVENTTYPE)) { 1632 if (evt.isType(ANIMATING_EVENTTYPE)) {
1575 if (fAnimating) { 1633 if (fAnimating) {
1576 this->nextSample(); 1634 this->nextSample();
1577 this->postAnimatingEvent(); 1635 this->postAnimatingEvent();
1578 } 1636 }
1579 return true; 1637 return true;
1580 } 1638 }
1581 if (evt.isType("set-curr-index")) { 1639 if (evt.isType("set-curr-index")) {
1582 this->goToSample(evt.getFast32()); 1640 this->goToSample(evt.getFast32());
1583 return true; 1641 return true;
1584 } 1642 }
1585 if (isInvalEvent(evt)) { 1643 if (isInvalEvent(evt)) {
1586 this->inval(nullptr); 1644 this->inval(nullptr);
1587 return true; 1645 return true;
1588 } 1646 }
1589 int selected = -1; 1647 int selected = -1;
1590 if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) { 1648 if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) {
1591 this->setDeviceType((DeviceType)selected); 1649 this->setDeviceType((DeviceType)selected);
1592 return true; 1650 return true;
1593 } 1651 }
1594 if (SkOSMenu::FindListIndex(evt, "ColorType", &selected)) { 1652 if (SkOSMenu::FindListIndex(evt, "ColorType", &selected)) {
1595 auto colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); 1653 fColorConfigIndex = selected;
1654 sk_sp<SkColorSpace> colorSpace = nullptr;
1655 switch (gConfig[selected].fColorSpace) {
1656 case kSRGB_OutputColorSpace:
1657 colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
1658 break;
1659 case kMonitor_OutputColorSpace:
1660 colorSpace = getMonitorColorSpace();
1661 if (!colorSpace) {
1662 // Fallback for platforms / machines where we can't get a mo nitor profile
1663 colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Name d);
1664 }
1665 break;
1666 case kLegacy_OutputColorSpace:
1667 default:
1668 // Do nothing
1669 break;
1670 }
1596 if (kRGBA_F16_SkColorType == gConfig[selected].fColorType) { 1671 if (kRGBA_F16_SkColorType == gConfig[selected].fColorType) {
1672 SkASSERT(colorSpace);
1597 colorSpace = colorSpace->makeLinearGamma(); 1673 colorSpace = colorSpace->makeLinearGamma();
1598 } 1674 }
1599 this->setDeviceColorType(gConfig[selected].fColorType, 1675 this->setDeviceColorType(gConfig[selected].fColorType, colorSpace);
1600 gConfig[selected].fSRGB ? colorSpace : nullptr) ;
1601 return true; 1676 return true;
1602 } 1677 }
1603 if (SkOSMenu::FindSwitchState(evt, "Slide Show", nullptr)) { 1678 if (SkOSMenu::FindSwitchState(evt, "Slide Show", nullptr)) {
1604 this->toggleSlideshow(); 1679 this->toggleSlideshow();
1605 return true; 1680 return true;
1606 } 1681 }
1607 if (SkOSMenu::FindTriState(evt, "AA", &fAAState) || 1682 if (SkOSMenu::FindTriState(evt, "AA", &fAAState) ||
1608 SkOSMenu::FindTriState(evt, "LCD", &fLCDState) || 1683 SkOSMenu::FindTriState(evt, "LCD", &fLCDState) ||
1609 SkOSMenu::FindListIndex(evt, "FilterQuality", &fFilterQualityIndex) || 1684 SkOSMenu::FindListIndex(evt, "FilterQuality", &fFilterQualityIndex) ||
1610 SkOSMenu::FindTriState(evt, "Subpixel", &fSubpixelState) || 1685 SkOSMenu::FindTriState(evt, "Subpixel", &fSubpixelState) ||
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 2189
2115 #if SK_SUPPORT_GPU 2190 #if SK_SUPPORT_GPU
2116 if (IsGpuDeviceType(fDeviceType) && 2191 if (IsGpuDeviceType(fDeviceType) &&
2117 fDevManager && 2192 fDevManager &&
2118 fDevManager->numColorSamples() > 0) { 2193 fDevManager->numColorSamples() > 0) {
2119 title.appendf(" [MSAA: %d]", 2194 title.appendf(" [MSAA: %d]",
2120 fDevManager->numColorSamples()); 2195 fDevManager->numColorSamples());
2121 } 2196 }
2122 #endif 2197 #endif
2123 2198
2124 title.appendf(" %s", find_config_name(this->info())); 2199 title.appendf(" %s", gConfig[fColorConfigIndex].fName);
2125 2200
2126 if (fDevManager && fDevManager->getColorBits() > 24) { 2201 if (fDevManager && fDevManager->getColorBits() > 24) {
2127 title.appendf(" %d bpc", fDevManager->getColorBits()); 2202 title.appendf(" %d bpc", fDevManager->getColorBits());
2128 } 2203 }
2129 2204
2130 this->setTitle(title.c_str()); 2205 this->setTitle(title.c_str());
2131 } 2206 }
2132 2207
2133 void SampleWindow::onSizeChange() { 2208 void SampleWindow::onSizeChange() {
2134 this->INHERITED::onSizeChange(); 2209 this->INHERITED::onSizeChange();
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 #ifdef SK_BUILD_FOR_MAC 2383 #ifdef SK_BUILD_FOR_MAC
2309 setenv("ANDROID_ROOT", "/android/device/data", 0); 2384 setenv("ANDROID_ROOT", "/android/device/data", 0);
2310 #endif 2385 #endif
2311 SkGraphics::Init(); 2386 SkGraphics::Init();
2312 SkEvent::Init(); 2387 SkEvent::Init();
2313 } 2388 }
2314 2389
2315 void application_term() { 2390 void application_term() {
2316 SkEvent::Term(); 2391 SkEvent::Term();
2317 } 2392 }
OLDNEW
« no previous file with comments | « samplecode/SampleApp.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698