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

Side by Side Diff: src/ports/SkScalerContext_win_dw.cpp

Issue 2019383003: Remove DWrite locks (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: update Created 4 years, 5 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 | « no previous file | 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 "SkTypes.h" 8 #include "SkTypes.h"
9 #if defined(SK_BUILD_FOR_WIN32) 9 #if defined(SK_BUILD_FOR_WIN32)
10 10
11 #undef GetGlyphIndices 11 #undef GetGlyphIndices
12 12
13 #include "SkDraw.h" 13 #include "SkDraw.h"
14 #include "SkDWrite.h" 14 #include "SkDWrite.h"
15 #include "SkDWriteGeometrySink.h" 15 #include "SkDWriteGeometrySink.h"
16 #include "SkEndian.h" 16 #include "SkEndian.h"
17 #include "SkGlyph.h" 17 #include "SkGlyph.h"
18 #include "SkHRESULT.h" 18 #include "SkHRESULT.h"
19 #include "SkMaskGamma.h" 19 #include "SkMaskGamma.h"
20 #include "SkMatrix22.h" 20 #include "SkMatrix22.h"
21 #include "SkMutex.h"
22 #include "SkOTTable_EBLC.h" 21 #include "SkOTTable_EBLC.h"
23 #include "SkOTTable_EBSC.h" 22 #include "SkOTTable_EBSC.h"
24 #include "SkOTTable_gasp.h" 23 #include "SkOTTable_gasp.h"
25 #include "SkOTTable_maxp.h" 24 #include "SkOTTable_maxp.h"
26 #include "SkPath.h" 25 #include "SkPath.h"
27 #include "SkRasterClip.h" 26 #include "SkRasterClip.h"
28 #include "SkScalerContext.h" 27 #include "SkScalerContext.h"
29 #include "SkScalerContext_win_dw.h" 28 #include "SkScalerContext_win_dw.h"
30 #include "SkSharedMutex.h"
31 #include "SkTScopedComPtr.h" 29 #include "SkTScopedComPtr.h"
32 #include "SkTypeface_win_dw.h" 30 #include "SkTypeface_win_dw.h"
33 31
34 #include <dwrite.h> 32 #include <dwrite.h>
35 #if SK_HAS_DWRITE_1_H 33 #if SK_HAS_DWRITE_1_H
36 # include <dwrite_1.h> 34 # include <dwrite_1.h>
37 #endif 35 #endif
38 36
39 /* Note:
40 * In versions 8 and 8.1 of Windows, some calls in DWrite are not thread safe.
41 * The DWriteFactoryMutex protects the calls that are problematic.
42 */
43 static SkSharedMutex DWriteFactoryMutex;
44
45 typedef SkAutoSharedMutexShared Shared;
46
47 static bool isLCD(const SkScalerContext::Rec& rec) { 37 static bool isLCD(const SkScalerContext::Rec& rec) {
48 return SkMask::kLCD16_Format == rec.fMaskFormat; 38 return SkMask::kLCD16_Format == rec.fMaskFormat;
49 } 39 }
50 40
51 static bool is_hinted_without_gasp(DWriteFontTypeface* typeface) { 41 static bool is_hinted_without_gasp(DWriteFontTypeface* typeface) {
52 SkAutoExclusive l(DWriteFactoryMutex);
53 AutoTDWriteTable<SkOTTableMaximumProfile> maxp(typeface->fDWriteFontFace.get ()); 42 AutoTDWriteTable<SkOTTableMaximumProfile> maxp(typeface->fDWriteFontFace.get ());
54 if (!maxp.fExists) { 43 if (!maxp.fExists) {
55 return false; 44 return false;
56 } 45 }
57 if (maxp.fSize < sizeof(SkOTTableMaximumProfile::Version::TT)) { 46 if (maxp.fSize < sizeof(SkOTTableMaximumProfile::Version::TT)) {
58 return false; 47 return false;
59 } 48 }
60 if (maxp->version.version != SkOTTableMaximumProfile::Version::TT::VERSION) { 49 if (maxp->version.version != SkOTTableMaximumProfile::Version::TT::VERSION) {
61 return false; 50 return false;
62 } 51 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 { 101 {
113 range->min = minPPEM + 1; 102 range->min = minPPEM + 1;
114 range->max = maxPPEM; 103 range->max = maxPPEM;
115 return; 104 return;
116 } 105 }
117 minPPEM = maxPPEM; 106 minPPEM = maxPPEM;
118 } 107 }
119 } 108 }
120 109
121 static bool has_bitmap_strike(DWriteFontTypeface* typeface, PPEMRange range) { 110 static bool has_bitmap_strike(DWriteFontTypeface* typeface, PPEMRange range) {
122 SkAutoExclusive l(DWriteFactoryMutex);
123 { 111 {
124 AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWrite FontFace.get()); 112 AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWrite FontFace.get());
125 if (!eblc.fExists) { 113 if (!eblc.fExists) {
126 return false; 114 return false;
127 } 115 }
128 if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation)) { 116 if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation)) {
129 return false; 117 return false;
130 } 118 }
131 if (eblc->version != SkOTTableEmbeddedBitmapLocation::version_initial) { 119 if (eblc->version != SkOTTableEmbeddedBitmapLocation::version_initial) {
132 return false; 120 return false;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 343
356 glyph->fAdvanceX = 0; 344 glyph->fAdvanceX = 0;
357 glyph->fAdvanceY = 0; 345 glyph->fAdvanceY = 0;
358 346
359 uint16_t glyphId = glyph->getGlyphID(); 347 uint16_t glyphId = glyph->getGlyphID();
360 DWRITE_GLYPH_METRICS gm; 348 DWRITE_GLYPH_METRICS gm;
361 349
362 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || 350 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
363 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) 351 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
364 { 352 {
365 SkAutoExclusive l(DWriteFactoryMutex);
366 HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics( 353 HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics(
367 fTextSizeMeasure, 354 fTextSizeMeasure,
368 1.0f, // pixelsPerDip 355 1.0f, // pixelsPerDip
369 &fGsA, 356 &fGsA,
370 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode, 357 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode,
371 &glyphId, 1, 358 &glyphId, 1,
372 &gm), 359 &gm),
373 "Could not get gdi compatible glyph metrics."); 360 "Could not get gdi compatible glyph metrics.");
374 } else { 361 } else {
375 SkAutoExclusive l(DWriteFactoryMutex);
376 HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm) , 362 HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm) ,
377 "Could not get design metrics."); 363 "Could not get design metrics.");
378 } 364 }
379 365
380 DWRITE_FONT_METRICS dwfm; 366 DWRITE_FONT_METRICS dwfm;
381 { 367 fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
382 Shared l(DWriteFactoryMutex);
383 fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
384 }
385 SkScalar advanceX = SkScalarMulDiv(fTextSizeMeasure, 368 SkScalar advanceX = SkScalarMulDiv(fTextSizeMeasure,
386 SkIntToScalar(gm.advanceWidth), 369 SkIntToScalar(gm.advanceWidth),
387 SkIntToScalar(dwfm.designUnitsPerEm)); 370 SkIntToScalar(dwfm.designUnitsPerEm));
388 371
389 SkVector vecs[1] = { { advanceX, 0 } }; 372 SkVector vecs[1] = { { advanceX, 0 } };
390 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || 373 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
391 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) 374 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
392 { 375 {
393 // DirectWrite produced 'compatible' metrics, but while close, 376 // DirectWrite produced 'compatible' metrics, but while close,
394 // the end result is not always an integer as it would be with GDI. 377 // the end result is not always an integer as it would be with GDI.
(...skipping 28 matching lines...) Expand all
423 run.glyphCount = 1; 406 run.glyphCount = 1;
424 run.glyphAdvances = &advance; 407 run.glyphAdvances = &advance;
425 run.fontFace = fTypeface->fDWriteFontFace.get(); 408 run.fontFace = fTypeface->fDWriteFontFace.get();
426 run.fontEmSize = SkScalarToFloat(fTextSizeRender); 409 run.fontEmSize = SkScalarToFloat(fTextSizeRender);
427 run.bidiLevel = 0; 410 run.bidiLevel = 0;
428 run.glyphIndices = &glyphId; 411 run.glyphIndices = &glyphId;
429 run.isSideways = FALSE; 412 run.isSideways = FALSE;
430 run.glyphOffsets = &offset; 413 run.glyphOffsets = &offset;
431 414
432 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; 415 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
433 { 416 HRM(fTypeface->fFactory->CreateGlyphRunAnalysis(
434 SkAutoExclusive l(DWriteFactoryMutex); 417 &run,
435 HRM(fTypeface->fFactory->CreateGlyphRunAnalysis( 418 1.0f, // pixelsPerDip,
436 &run, 419 &fXform,
437 1.0f, // pixelsPerDip, 420 renderingMode,
438 &fXform, 421 fMeasuringMode,
439 renderingMode, 422 0.0f, // baselineOriginX,
440 fMeasuringMode, 423 0.0f, // baselineOriginY,
441 0.0f, // baselineOriginX, 424 &glyphRunAnalysis),
442 0.0f, // baselineOriginY, 425 "Could not create glyph run analysis.");
443 &glyphRunAnalysis), 426 HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox),
444 "Could not create glyph run analysis."); 427 "Could not get texture bounds.");
445 }
446 {
447 Shared l(DWriteFactoryMutex);
448 HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox),
449 "Could not get texture bounds.");
450 }
451 return S_OK; 428 return S_OK;
452 } 429 }
453 430
454 /** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like 431 /** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like
455 * { 0x80000000, 0x80000000, 0x80000000, 0x80000000 } 432 * { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
456 * for small, but not quite zero, sized glyphs. 433 * for small, but not quite zero, sized glyphs.
457 * Only set as non-empty if the returned bounds are non-empty. 434 * Only set as non-empty if the returned bounds are non-empty.
458 */ 435 */
459 static bool glyph_check_and_set_bounds(SkGlyph* glyph, const RECT& bbox) { 436 static bool glyph_check_and_set_bounds(SkGlyph* glyph, const RECT& bbox) {
460 if (bbox.left >= bbox.right || bbox.top >= bbox.bottom) { 437 if (bbox.left >= bbox.right || bbox.top >= bbox.bottom) {
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 run.glyphAdvances = &advance; 705 run.glyphAdvances = &advance;
729 run.fontFace = fTypeface->fDWriteFontFace.get(); 706 run.fontFace = fTypeface->fDWriteFontFace.get();
730 run.fontEmSize = SkScalarToFloat(fTextSizeRender); 707 run.fontEmSize = SkScalarToFloat(fTextSizeRender);
731 run.bidiLevel = 0; 708 run.bidiLevel = 0;
732 run.glyphIndices = &index; 709 run.glyphIndices = &index;
733 run.isSideways = FALSE; 710 run.isSideways = FALSE;
734 run.glyphOffsets = &offset; 711 run.glyphOffsets = &offset;
735 { 712 {
736 713
737 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; 714 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
738 { 715 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
739 SkAutoExclusive l(DWriteFactoryMutex); 716 1.0f, // pixelsPerDip,
740 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, 717 &fXform,
741 1.0f, // pixelsPerDip, 718 renderingMode,
742 &fXform, 719 fMeasuringMode,
743 renderingMode, 720 0.0f, // baselineOriginX,
744 fMeasuringMode, 721 0.0f, // baselineOriginY,
745 0.0f, // baselineOriginX, 722 &glyphRunAnalysis),
746 0.0f, // baselineOriginY, 723 "Could not create glyph run analysis.");
747 &glyphRunAnalysis),
748 "Could not create glyph run analysis.");
749 }
750 //NOTE: this assumes that the glyph has already been measured 724 //NOTE: this assumes that the glyph has already been measured
751 //with an exact same glyph run analysis. 725 //with an exact same glyph run analysis.
752 RECT bbox; 726 RECT bbox;
753 bbox.left = glyph.fLeft; 727 bbox.left = glyph.fLeft;
754 bbox.top = glyph.fTop; 728 bbox.top = glyph.fTop;
755 bbox.right = glyph.fLeft + glyph.fWidth; 729 bbox.right = glyph.fLeft + glyph.fWidth;
756 bbox.bottom = glyph.fTop + glyph.fHeight; 730 bbox.bottom = glyph.fTop + glyph.fHeight;
757 { 731 HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
758 Shared l(DWriteFactoryMutex); 732 &bbox,
759 HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType, 733 fBits.begin(),
760 &bbox, 734 sizeNeeded),
761 fBits.begin(), 735 "Could not draw mask.");
762 sizeNeeded),
763 "Could not draw mask.");
764 }
765 } 736 }
766 return fBits.begin(); 737 return fBits.begin();
767 } 738 }
768 739
769 #if SK_HAS_DWRITE_2_H 740 #if SK_HAS_DWRITE_2_H
770 void SkScalerContext_DW::generateColorGlyphImage(const SkGlyph& glyph) { 741 void SkScalerContext_DW::generateColorGlyphImage(const SkGlyph& glyph) {
771 SkASSERT(isColorGlyph(glyph)); 742 SkASSERT(isColorGlyph(glyph));
772 SkASSERT(glyph.fMaskFormat == SkMask::Format::kARGB32_Format); 743 SkASSERT(glyph.fMaskFormat == SkMask::Format::kARGB32_Format);
773 744
774 memset(glyph.fImage, 0, glyph.computeImageSize()); 745 memset(glyph.fImage, 0, glyph.computeImageSize());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 // If this assert ever fires, we should verify that the color is ren dered properly. 783 // If this assert ever fires, we should verify that the color is ren dered properly.
813 SkASSERT(false); 784 SkASSERT(false);
814 color = fRec.getLuminanceColor(); 785 color = fRec.getLuminanceColor();
815 } 786 }
816 paint.setColor(color); 787 paint.setColor(color);
817 788
818 SkPath path; 789 SkPath path;
819 SkTScopedComPtr<IDWriteGeometrySink> geometryToPath; 790 SkTScopedComPtr<IDWriteGeometrySink> geometryToPath;
820 HRVM(SkDWriteGeometrySink::Create(&path, &geometryToPath), 791 HRVM(SkDWriteGeometrySink::Create(&path, &geometryToPath),
821 "Could not create geometry to path converter."); 792 "Could not create geometry to path converter.");
822 { 793 HRVM(colorGlyph->glyphRun.fontFace->GetGlyphRunOutline(
823 SkAutoExclusive l(DWriteFactoryMutex); 794 colorGlyph->glyphRun.fontEmSize,
824 HRVM(colorGlyph->glyphRun.fontFace->GetGlyphRunOutline( 795 colorGlyph->glyphRun.glyphIndices,
825 colorGlyph->glyphRun.fontEmSize, 796 colorGlyph->glyphRun.glyphAdvances,
826 colorGlyph->glyphRun.glyphIndices, 797 colorGlyph->glyphRun.glyphOffsets,
827 colorGlyph->glyphRun.glyphAdvances, 798 colorGlyph->glyphRun.glyphCount,
828 colorGlyph->glyphRun.glyphOffsets, 799 colorGlyph->glyphRun.isSideways,
829 colorGlyph->glyphRun.glyphCount, 800 colorGlyph->glyphRun.bidiLevel % 2, //rtl
830 colorGlyph->glyphRun.isSideways, 801 geometryToPath.get()),
831 colorGlyph->glyphRun.bidiLevel % 2, //rtl 802 "Could not create glyph outline.");
832 geometryToPath.get()),
833 "Could not create glyph outline.");
834 }
835 draw.drawPath(path, paint, nullptr, true /* pathIsMutable */); 803 draw.drawPath(path, paint, nullptr, true /* pathIsMutable */);
836 } 804 }
837 } 805 }
838 #endif 806 #endif
839 807
840 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { 808 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
841 //Create the mask. 809 //Create the mask.
842 DWRITE_RENDERING_MODE renderingMode = fRenderingMode; 810 DWRITE_RENDERING_MODE renderingMode = fRenderingMode;
843 DWRITE_TEXTURE_TYPE textureType = fTextureType; 811 DWRITE_TEXTURE_TYPE textureType = fTextureType;
844 if (glyph.fForceBW) { 812 if (glyph.fForceBW) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 858
891 void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) { 859 void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
892 SkASSERT(path); 860 SkASSERT(path);
893 861
894 path->reset(); 862 path->reset();
895 863
896 SkTScopedComPtr<IDWriteGeometrySink> geometryToPath; 864 SkTScopedComPtr<IDWriteGeometrySink> geometryToPath;
897 HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath), 865 HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath),
898 "Could not create geometry to path converter."); 866 "Could not create geometry to path converter.");
899 uint16_t glyphId = glyph.getGlyphID(); 867 uint16_t glyphId = glyph.getGlyphID();
900 { 868 //TODO: convert to<->from DIUs? This would make a difference if hinting.
901 SkAutoExclusive l(DWriteFactoryMutex); 869 //It may not be needed, it appears that DirectWrite only hints at em size.
902 //TODO: convert to<->from DIUs? This would make a difference if hinting. 870 HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fTextSiz eRender),
903 //It may not be needed, it appears that DirectWrite only hints at em siz e. 871 &glyphId,
904 HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fTex tSizeRender), 872 nullptr, //advances
905 &glyphId, 873 nullptr, //offsets
906 nullptr, //advances 874 1, //num glyphs
907 nullptr, //offsets 875 FALSE, //sideways
908 1, //num glyphs 876 FALSE, //rtl
909 FALSE, //sideways 877 geometryToPath.get()),
910 FALSE, //rtl 878 "Could not create glyph outline.");
911 geometryToPath.get()),
912 "Could not create glyph outline.");
913 }
914 879
915 path->transform(fSkXform); 880 path->transform(fSkXform);
916 } 881 }
917 882
918 #endif//defined(SK_BUILD_FOR_WIN32) 883 #endif//defined(SK_BUILD_FOR_WIN32)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698