blob: 20123754e2a145098842a1e7f74cfc81e2400f3c [file] [log] [blame]
tomhudson@google.com168e6342012-04-18 17:49:20 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
joshualittb0a8a372014-09-23 09:50:21 -07008#ifndef GrProcessor_DEFINED
9#define GrProcessor_DEFINED
tomhudson@google.com168e6342012-04-18 17:49:20 +000010
joshualittb0a8a372014-09-23 09:50:21 -070011#include "GrBackendProcessorFactory.h"
bsalomon@google.com371e1052013-01-11 21:08:55 +000012#include "GrColor.h"
joshualittb0a8a372014-09-23 09:50:21 -070013#include "GrProcessorUnitTest.h"
bsalomon95740982014-09-04 13:12:37 -070014#include "GrProgramElement.h"
bsalomon@google.com047696c2012-09-11 13:29:29 +000015#include "GrTextureAccess.h"
egdaniel9e4d6d12014-10-15 13:49:02 -070016#include "SkMath.h"
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000017
tomhudson@google.com168e6342012-04-18 17:49:20 +000018class GrContext;
bsalomon@google.com77af6802013-10-02 13:04:56 +000019class GrCoordTransform;
egdaniel605dd0f2014-11-12 08:35:25 -080020class GrInvariantOutput;
bsalomon95740982014-09-04 13:12:37 -070021
bsalomon98b33eb2014-10-15 11:05:26 -070022/** Provides custom shader code to the Ganesh shading pipeline. GrProcessor objects *must* be
23 immutable: after being constructed, their fields may not change.
bsalomon@google.com0ac6af42013-01-16 15:16:18 +000024
joshualittb0a8a372014-09-23 09:50:21 -070025 Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an
bsalomon98b33eb2014-10-15 11:05:26 -070026 processor must reach 0 before the thread terminates and the pool is destroyed. To create a
27 static processor use the helper macro GR_CREATE_STATIC_PROCESSOR declared below.
28 */
joshualittb0a8a372014-09-23 09:50:21 -070029class GrProcessor : public GrProgramElement {
tomhudson@google.com168e6342012-04-18 17:49:20 +000030public:
joshualittb0a8a372014-09-23 09:50:21 -070031 SK_DECLARE_INST_COUNT(GrProcessor)
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000032
joshualittb0a8a372014-09-23 09:50:21 -070033 virtual ~GrProcessor();
tomhudson@google.com168e6342012-04-18 17:49:20 +000034
bsalomon@google.com371e1052013-01-11 21:08:55 +000035 /**
egdaniel1a8ecdf2014-10-03 06:24:12 -070036 * This function is used to perform optimizations. When called the invarientOuput param
bsalomon98b33eb2014-10-15 11:05:26 -070037 * indicate whether the input components to this processor in the FS will have known values.
egdaniel1a8ecdf2014-10-03 06:24:12 -070038 * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent
39 * member indicates whether the input will be 1 or 4 bytes. The function updates the members of
40 * inout to indicate known values of its output. A component of the color member only has
41 * meaning if the corresponding bit in validFlags is set.
bsalomon@google.com371e1052013-01-11 21:08:55 +000042 */
egdaniel605dd0f2014-11-12 08:35:25 -080043 void computeInvariantOutput(GrInvariantOutput* inout) const;
tomhudson@google.com168e6342012-04-18 17:49:20 +000044
bsalomon@google.com422e81a2012-10-25 14:11:03 +000045 /** This object, besides creating back-end-specific helper objects, is used for run-time-type-
46 identification. The factory should be an instance of templated class,
bsalomonb762cb52014-10-15 11:25:21 -070047 GrTBackendProcessorFactory. It is templated on the subclass of GrProcessor. The subclass
48 must have a nested type (or typedef) named GLProcessor which will be the subclass of
joshualittb0a8a372014-09-23 09:50:21 -070049 GrGLProcessor created by the factory.
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000050
51 Example:
bsalomon98b33eb2014-10-15 11:05:26 -070052 class MyCustomProcessor : public GrProcessor {
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000053 ...
bsalomonb762cb52014-10-15 11:25:21 -070054 virtual const GrBackendProcessorFactory& getFactory() const SK_OVERRIDE {
55 return GrTBackendProcessorFactory<MyCustomProcessor>::getInstance();
bsalomon@google.comae4f96a2012-05-18 19:54:48 +000056 }
57 ...
58 };
59 */
joshualittb0a8a372014-09-23 09:50:21 -070060 virtual const GrBackendProcessorFactory& getFactory() const = 0;
tomhudson@google.comb88bbd22012-05-01 12:48:07 +000061
bsalomon98b33eb2014-10-15 11:05:26 -070062 /** Human-meaningful string to identify this prcoessor; may be embedded
twiz@google.coma5e65ec2012-08-02 15:15:16 +000063 in generated shader code. */
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000064 const char* name() const;
bsalomon@google.com289efe02012-05-21 20:57:59 +000065
bsalomon@google.com50db75c2013-01-11 13:54:30 +000066 int numTextures() const { return fTextureAccesses.count(); }
tomhudson@google.comd8f856c2012-05-10 12:13:36 +000067
bsalomon@google.com6d003d12012-09-11 15:45:20 +000068 /** Returns the access pattern for the texture at index. index must be valid according to
69 numTextures(). */
bsalomon@google.com50db75c2013-01-11 13:54:30 +000070 const GrTextureAccess& textureAccess(int index) const { return *fTextureAccesses[index]; }
bsalomon@google.com6d003d12012-09-11 15:45:20 +000071
72 /** Shortcut for textureAccess(index).texture(); */
73 GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
twiz@google.coma5e65ec2012-08-02 15:15:16 +000074
bsalomon98b33eb2014-10-15 11:05:26 -070075 /** Will this processor read the fragment position? */
commit-bot@chromium.org8d47ddc2013-05-09 14:55:46 +000076 bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +000077
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000078 void* operator new(size_t size);
79 void operator delete(void* target);
80
bsalomon@google.comd42aca32013-04-23 15:37:27 +000081 void* operator new(size_t size, void* placement) {
82 return ::operator new(size, placement);
83 }
84 void operator delete(void* target, void* placement) {
85 ::operator delete(target, placement);
86 }
87
joshualitt49586be2014-09-16 08:21:41 -070088 /**
joshualittb0a8a372014-09-23 09:50:21 -070089 * Helper for down-casting to a GrProcessor subclass
joshualitt49586be2014-09-16 08:21:41 -070090 */
91 template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
92
bsalomon@google.com50db75c2013-01-11 13:54:30 +000093protected:
bsalomon420d7e92014-10-16 09:18:09 -070094 GrProcessor() : fWillReadFragmentPosition(false) {}
95
bsalomon@google.com50db75c2013-01-11 13:54:30 +000096 /**
bsalomon98b33eb2014-10-15 11:05:26 -070097 * Subclasses call this from their constructor to register GrTextureAccesses. The processor
commit-bot@chromium.org91a798f2013-09-06 15:31:06 +000098 * subclass manages the lifetime of the accesses (this function only stores a pointer). The
joshualittb0a8a372014-09-23 09:50:21 -070099 * GrTextureAccess is typically a member field of the GrProcessor subclass. This must only be
100 * called from the constructor because GrProcessors are immutable.
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000101 */
102 void addTextureAccess(const GrTextureAccess* textureAccess);
103
bsalomon420d7e92014-10-16 09:18:09 -0700104 bool hasSameTextureAccesses(const GrProcessor&) const;
commit-bot@chromium.org8d47ddc2013-05-09 14:55:46 +0000105
106 /**
bsalomon98b33eb2014-10-15 11:05:26 -0700107 * If the prcoessor will generate a backend-specific processor that will read the fragment
108 * position in the FS then it must call this method from its constructor. Otherwise, the
109 * request to access the fragment position will be denied.
commit-bot@chromium.org8d47ddc2013-05-09 14:55:46 +0000110 */
111 void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000112
bsalomon0e08fc12014-10-15 08:19:04 -0700113private:
egdaniel1a8ecdf2014-10-03 06:24:12 -0700114 /**
115 * Subclass implements this to support getConstantColorComponents(...).
116 */
egdaniel605dd0f2014-11-12 08:35:25 -0800117 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000118
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000119 SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
commit-bot@chromium.org8d47ddc2013-05-09 14:55:46 +0000120 bool fWillReadFragmentPosition;
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000121
bsalomon95740982014-09-04 13:12:37 -0700122 typedef GrProgramElement INHERITED;
tomhudson@google.com168e6342012-04-18 17:49:20 +0000123};
124
bsalomon98b33eb2014-10-15 11:05:26 -0700125
126/**
127 * This creates a processor outside of the memory pool. The processor's destructor will be called
128 * at global destruction time. NAME will be the name of the created instance.
129 */
130#define GR_CREATE_STATIC_PROCESSOR(NAME, PROC_CLASS, ARGS) \
131static SkAlignedSStorage<sizeof(PROC_CLASS)> g_##NAME##_Storage; \
132static PROC_CLASS* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), PROC_CLASS, ARGS); \
133static SkAutoTDestroy<GrProcessor> NAME##_ad(NAME);
134
tomhudson@google.com168e6342012-04-18 17:49:20 +0000135#endif