aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2015-09-08 08:19:33 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-08 08:19:34 -0700
commitbbd40183ae5f5dd3ae6e8ad3cf89cf5c27ce754b (patch)
treeab69f0d687d4496e862f033714643b84ac779036
parenta5f46e18212e8f4812ae25fda3acc6a5217613b1 (diff)
Port SkLazyFnPtr users to SkOncePtr.
First baby step on road to replacing SkLazyFnPtr, SkLazyPtr, and SkOnce. One of those very unusual times you get to use a function type, not a function pointer type! BUG=skia: Review URL: https://codereview.chromium.org/1317263007
-rw-r--r--src/core/SkLazyFnPtr.h66
-rw-r--r--src/ports/SkFontHost_mac.cpp37
2 files changed, 15 insertions, 88 deletions
diff --git a/src/core/SkLazyFnPtr.h b/src/core/SkLazyFnPtr.h
deleted file mode 100644
index 153578201a..0000000000
--- a/src/core/SkLazyFnPtr.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkLazyFnPtr_DEFINED
-#define SkLazyFnPtr_DEFINED
-
-/** Declare a lazily-chosen static function pointer of type F.
- *
- * Example usage:
- *
- * typedef int (*FooImpl)(int, int);
- *
- * static FooImpl choose_foo() { return ... };
- *
- * int Foo(int a, int b) {
- * SK_DECLARE_STATIC_LAZY_FN_PTR(FooImpl, foo, choose_foo);
- * return foo.get()(a, b);
- * }
- *
- * You can think of SK_DECLARE_STATIC_LAZY_FN_PTR as a cheaper specialization of SkOnce.
- * There is no mutex, and in the fast path, no memory barriers are issued.
- *
- * This must be used in a global or function scope, not as a class member.
- */
-#define SK_DECLARE_STATIC_LAZY_FN_PTR(F, name, Choose) static Private::SkLazyFnPtr<F, Choose> name
-
-
-// Everything below here is private implementation details. Don't touch, don't even look.
-
-#include "SkAtomics.h"
-
-namespace Private {
-
-// This has no constructor and must be zero-initialized (the macro above does this).
-template <typename F, F (*Choose)()>
-class SkLazyFnPtr {
-public:
- F get() {
- // First, try reading to see if it's already set.
- F fn = (F)sk_atomic_load(&fPtr, sk_memory_order_relaxed);
- if (fn != nullptr) {
- return fn;
- }
-
- // We think it's not already set.
- fn = Choose();
-
- // No particular memory barriers needed; we're not guarding anything but the pointer itself.
- F prev = (F)sk_atomic_cas(&fPtr, nullptr, (void*)fn);
-
- // If prev != nullptr, someone snuck in and set fPtr concurrently.
- // If prev == nullptr, we did write fn to fPtr.
- return prev != nullptr ? prev : fn;
- }
-
-private:
- void* fPtr;
-};
-
-} // namespace Private
-
-#endif//SkLazyFnPtr_DEFINED
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 343936c673..7d90d84695 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -28,7 +28,6 @@
#include "SkFontDescriptor.h"
#include "SkFontMgr.h"
#include "SkGlyph.h"
-#include "SkLazyFnPtr.h"
#include "SkMaskGamma.h"
#include "SkMutex.h"
#include "SkOTTable_glyf.h"
@@ -36,6 +35,7 @@
#include "SkOTTable_hhea.h"
#include "SkOTTable_loca.h"
#include "SkOTUtils.h"
+#include "SkOncePtr.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkSFNTHeader.h"
@@ -770,34 +770,27 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit);
}
-extern "C" {
-
-/** CTFontDrawGlyphs was introduced in 10.7. */
-typedef void (*CTFontDrawGlyphsProc)(CTFontRef, const CGGlyph[], const CGPoint[],
- size_t, CGContextRef);
-
-/** This is an implementation of CTFontDrawGlyphs for 10.6. */
-static void sk_legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGPoint points[],
- size_t count, CGContextRef cg)
-{
+/** This is an implementation of CTFontDrawGlyphs for 10.6; it was introduced in 10.7. */
+static void legacy_CTFontDrawGlyphs(CTFontRef, const CGGlyph glyphs[], const CGPoint points[],
+ size_t count, CGContextRef cg) {
CGContextShowGlyphsAtPositions(cg, glyphs, points, count);
}
-}
+typedef decltype(legacy_CTFontDrawGlyphs) CTFontDrawGlyphsProc;
-CTFontDrawGlyphsProc SkChooseCTFontDrawGlyphs() {
- CTFontDrawGlyphsProc realCTFontDrawGlyphs;
- *reinterpret_cast<void**>(&realCTFontDrawGlyphs) = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs");
- return realCTFontDrawGlyphs ? realCTFontDrawGlyphs : sk_legacy_CTFontDrawGlyphs;
-};
+static CTFontDrawGlyphsProc* choose_CTFontDrawGlyphs() {
+ if (void* real = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs")) {
+ return (CTFontDrawGlyphsProc*)real;
+ }
+ return &legacy_CTFontDrawGlyphs;
+}
-SK_DECLARE_STATIC_LAZY_FN_PTR(CTFontDrawGlyphsProc, gCTFontDrawGlyphs, SkChooseCTFontDrawGlyphs);
+SK_DECLARE_STATIC_ONCE_PTR(CTFontDrawGlyphsProc, gCTFontDrawGlyphs);
CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph,
CGGlyph glyphID, size_t* rowBytesPtr,
- bool generateA8FromLCD)
-{
- CTFontDrawGlyphsProc ctFontDrawGlyphs = gCTFontDrawGlyphs.get();
+ bool generateA8FromLCD) {
+ auto ctFontDrawGlyphs = gCTFontDrawGlyphs.get(choose_CTFontDrawGlyphs);
if (!fRGBSpace) {
//It doesn't appear to matter what color space is specified.
@@ -867,7 +860,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
fDoAA = !doAA;
fDoLCD = !doLCD;
- if (sk_legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) {
+ if (legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) {
// CTFontDrawGlyphs will apply the font, font size, and font matrix to the CGContext.
// Our 'fake' one does not, so set up the CGContext here.
CGContextSetFont(fCG, context.fCGFont);