diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-29 18:29:48 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-29 18:29:48 +0000 |
commit | d3c6b3f1c89ad1336830957a1e9b235dd86910f2 (patch) | |
tree | 0945e97d54ddbf462b493aafd0e12f75d818a88e | |
parent | 448e2a3b3935d91e7bf84dc5b0367b92d2e2a518 (diff) |
Tinker with SkLazyFnPtr a bit.
I moved the choice function from a get() arg to a template parameter.
I think this removes some of the overemphasis on "choose" from the call
site, making it a bit more clear it's normally very cheap.
It's also now more in line with what I'm thinking now for the general
SkLazyPtr<T>, which needs a "create" parameter just like SkLazyFnPtr's
"choose", but also a "destroy" that it might use both in .get() but also
at process exit. That "destroy" needs to be made part of the type to be
called at exit, so might as well make "create" and "choose" template
parameters too so it's all consistent.
Also, add (C).
BUG=skia:
R=bungeman@google.com, mtklein@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/298393005
git-svn-id: http://skia.googlecode.com/svn/trunk@14971 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkLazyFnPtr.h | 25 | ||||
-rw-r--r-- | src/core/SkUtils.cpp | 36 |
2 files changed, 38 insertions, 23 deletions
diff --git a/src/core/SkLazyFnPtr.h b/src/core/SkLazyFnPtr.h index 94594b4aeb..464e061a13 100644 --- a/src/core/SkLazyFnPtr.h +++ b/src/core/SkLazyFnPtr.h @@ -1,3 +1,10 @@ +/* + * 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 @@ -10,8 +17,8 @@ * static FooImpl choose_foo() { return ... }; * * int Foo(int a, int b) { - * SK_DECLARE_STATIC_LAZY_FN_PTR(FooImpl, choice); - * return choice.get(choose_foo)(a, 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. @@ -19,7 +26,7 @@ * * This must be used in a global or function scope, not as a class member. */ -#define SK_DECLARE_STATIC_LAZY_FN_PTR(F, name) static Private::SkLazyFnPtr<F> name = { NULL } +#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. @@ -29,10 +36,11 @@ namespace Private { -// This has no constructor and is link-time initialized, so its members must be public. -template <typename F> -struct SkLazyFnPtr { - F get(F (*choose)()) { +// 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_ANNOTATE_UNPROTECTED_READ(fPtr); if (fn != NULL) { @@ -40,7 +48,7 @@ struct SkLazyFnPtr { } // We think it's not already set. - fn = choose(); + fn = Choose(); // No particular memory barriers needed; we're not guarding anything but the pointer itself. F prev = (F)sk_atomic_cas(&fPtr, NULL, (void*)fn); @@ -50,6 +58,7 @@ struct SkLazyFnPtr { return prev != NULL ? prev : fn; } +private: void* fPtr; }; diff --git a/src/core/SkUtils.cpp b/src/core/SkUtils.cpp index 591a198c65..eff718b20f 100644 --- a/src/core/SkUtils.cpp +++ b/src/core/SkUtils.cpp @@ -113,34 +113,40 @@ static void sk_memcpy32_portable(uint32_t dst[], const uint32_t src[], int count memcpy(dst, src, count * sizeof(uint32_t)); } -static SkMemset16Proc choose_memset16() { +namespace { +// These three methods technically need external linkage to be passed as template parameters. +// Since they can't be static, we hide them in an anonymous namespace instead. + +SkMemset16Proc choose_memset16() { SkMemset16Proc proc = SkMemset16GetPlatformProc(); return proc ? proc : sk_memset16_portable; } -void sk_memset16(uint16_t dst[], uint16_t value, int count) { - SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemset16Proc, choice); - return choice.get(choose_memset16)(dst, value, count); -} - -static SkMemset32Proc choose_memset32() { +SkMemset32Proc choose_memset32() { SkMemset32Proc proc = SkMemset32GetPlatformProc(); return proc ? proc : sk_memset32_portable; } -void sk_memset32(uint32_t dst[], uint32_t value, int count) { - SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemset32Proc, choice); - return choice.get(choose_memset32)(dst, value, count); -} - -static SkMemcpy32Proc choose_memcpy32() { +SkMemcpy32Proc choose_memcpy32() { SkMemcpy32Proc proc = SkMemcpy32GetPlatformProc(); return proc ? proc : sk_memcpy32_portable; } +} // namespace + +void sk_memset16(uint16_t dst[], uint16_t value, int count) { + SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemset16Proc, proc, choose_memset16); + proc.get()(dst, value, count); +} + +void sk_memset32(uint32_t dst[], uint32_t value, int count) { + SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemset32Proc, proc, choose_memset32); + proc.get()(dst, value, count); +} + void sk_memcpy32(uint32_t dst[], const uint32_t src[], int count) { - SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemcpy32Proc, choice); - return choice.get(choose_memcpy32)(dst, src, count); + SK_DECLARE_STATIC_LAZY_FN_PTR(SkMemcpy32Proc, proc, choose_memcpy32); + proc.get()(dst, src, count); } /////////////////////////////////////////////////////////////////////////////// |