2013-07-12 18:22:49 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2013 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This header provides some of the helpers (std::integral_constant) and
|
|
|
|
* type transformations (std::conditional) which will become available with
|
|
|
|
* C++11 in the type_traits header.
|
|
|
|
*
|
|
|
|
* Because we lack constexpr, we cannot mimic
|
|
|
|
* std::integral_constant::'constexpr operator T()'.
|
|
|
|
* As a result we introduce SkTBool and SkTIf similar to Boost in order to
|
|
|
|
* minimize the visual noise of many uses of '::value'.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SkTLogic_DEFINED
|
|
|
|
#define SkTLogic_DEFINED
|
|
|
|
|
|
|
|
/** Represents a templated integer constant.
|
|
|
|
* Pre-C++11 version of std::integral_constant.
|
|
|
|
*/
|
|
|
|
template <typename T, T v> struct SkTIntegralConstant {
|
|
|
|
static const T value = v;
|
|
|
|
typedef T value_type;
|
|
|
|
typedef SkTIntegralConstant<T, v> type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Convenience specialization of SkTIntegralConstant. */
|
|
|
|
template <bool b> struct SkTBool : SkTIntegralConstant<bool, b> { };
|
|
|
|
|
|
|
|
/** Pre-C++11 version of std::true_type. */
|
|
|
|
typedef SkTBool<true> SkTrue;
|
|
|
|
|
|
|
|
/** Pre-C++11 version of std::false_type. */
|
|
|
|
typedef SkTBool<false> SkFalse;
|
|
|
|
|
|
|
|
/** SkTIf_c::type = (condition) ? T : F;
|
|
|
|
* Pre-C++11 version of std::conditional.
|
|
|
|
*/
|
|
|
|
template <bool condition, typename T, typename F> struct SkTIf_c {
|
|
|
|
typedef F type;
|
|
|
|
};
|
|
|
|
template <typename T, typename F> struct SkTIf_c<true, T, F> {
|
|
|
|
typedef T type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** SkTIf::type = (Condition::value) ? T : F; */
|
|
|
|
template <typename Condition, typename T, typename F> struct SkTIf {
|
|
|
|
typedef typename SkTIf_c<static_cast<bool>(Condition::value), T, F>::type type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** SkTMux::type = (a && b) ? Both : (a) ? A : (b) ? B : Neither; */
|
|
|
|
template <typename a, typename b, typename Both, typename A, typename B, typename Neither>
|
|
|
|
struct SkTMux {
|
|
|
|
typedef typename SkTIf<a, typename SkTIf<b, Both, A>::type,
|
|
|
|
typename SkTIf<b, B, Neither>::type>::type type;
|
|
|
|
};
|
|
|
|
|
2014-04-28 16:19:45 +00:00
|
|
|
/** SkTEnableIf_c::type = (condition) ? T : [does not exist]; */
|
|
|
|
template <bool condition, class T = void> struct SkTEnableIf_c { };
|
|
|
|
template <class T> struct SkTEnableIf_c<true, T> {
|
|
|
|
typedef T type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** SkTEnableIf::type = (Condition::value) ? T : [does not exist]; */
|
|
|
|
template <class Condition, class T = void> struct SkTEnableIf
|
|
|
|
: public SkTEnableIf_c<static_cast<bool>(Condition::value), T> { };
|
|
|
|
|
|
|
|
/** Use as a return type to enable a function only when cond_type::value is true,
|
|
|
|
* like C++14's std::enable_if_t. E.g. (N.B. this is a dumb example.)
|
|
|
|
* SK_WHEN(SkTrue, int) f(void* ptr) { return 1; }
|
|
|
|
* SK_WHEN(!SkTrue, int) f(void* ptr) { return 2; }
|
|
|
|
*/
|
|
|
|
#define SK_WHEN(cond_prefix, T) typename SkTEnableIf_c<cond_prefix::value, T>::type
|
|
|
|
|
|
|
|
// See http://en.wikibooks.org/wiki/More_C++_Idioms/Member_Detector
|
|
|
|
#define SK_CREATE_MEMBER_DETECTOR(member) \
|
|
|
|
template <typename T> \
|
|
|
|
class HasMember_##member { \
|
|
|
|
struct Fallback { int member; }; \
|
|
|
|
struct Derived : T, Fallback {}; \
|
|
|
|
template <typename U, U> struct Check; \
|
|
|
|
template <typename U> static uint8_t func(Check<int Fallback::*, &U::member>*); \
|
|
|
|
template <typename U> static uint16_t func(...); \
|
|
|
|
public: \
|
|
|
|
typedef HasMember_##member type; \
|
|
|
|
static const bool value = sizeof(func<Derived>(NULL)) == sizeof(uint16_t); \
|
|
|
|
}
|
|
|
|
|
Add pattern matchers for SkRecord
This is a mid-level library for finding patterns of commands in an SkRecord. At the API level, it's a bit regex inspired. Some examples:
- Pattern1<Is<DrawRect>> matches a single DrawRect
- Pattern1<Star<Is<DrawRect>>> matches 0 or more DrawRects
- Pattern2<Is<ClipRect>, Is<DrawRect>> matches a single clip rect followed by a single draw rect
- Pattern3<Is<Save>, Star<IsDraw>, Is<Restore>> matches a single Save, followed by any number of Draws, followed by Restore
- Pattern1<Or<Is<DrawRect>, Is<ClipRect>>> matches a DrawRect or a ClipRect
- Pattern1<Not<Is<ClipRect>>> matches a command that's notClipRect.
Once you have a pattern, you can call .search() on it to step through ranges of matching commands. This means patterns can replace most of the custom iteration logic for optimization passes: the generic pattern searching steps through all the optimization candidates, which optimization-specific code further inspects and mutates.
SkRecordTraits is now unused. Bye bye!
Generated code and performance of SkRecordOpts is very similar to what it was before. (I had to use SK_ALWAYS_INLINE in a few places to make this so.)
BUG=skia:2378
R=fmalita@chromium.org, bungeman@google.com, mtklein@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/263063002
git-svn-id: http://skia.googlecode.com/svn/trunk@14582 2bbb7eff-a529-9590-31e7-b0007b416f81
2014-05-05 21:59:52 +00:00
|
|
|
// Same sort of thing as SK_CREATE_MEMBER_DETECTOR, but checks for the existence of a nested type.
|
|
|
|
#define SK_CREATE_TYPE_DETECTOR(type) \
|
|
|
|
template <typename T> \
|
|
|
|
class HasType_##type { \
|
|
|
|
template <typename U> static uint8_t func(typename U::type*); \
|
|
|
|
template <typename U> static uint16_t func(...); \
|
|
|
|
public: \
|
|
|
|
static const bool value = sizeof(func<T>(NULL)) == sizeof(uint8_t); \
|
|
|
|
}
|
|
|
|
|
2013-07-12 18:31:59 +00:00
|
|
|
#endif
|