From 4b6db42d3d733652365c4fcf2a6f63deba5e1f72 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 28 Oct 2018 16:10:21 -0700 Subject: [PATCH] GPU state cleanup --- .../gpu-gl-common/src/gpu/gl/GLState.cpp | 2 +- libraries/gpu/src/gpu/Context.h | 146 ++++++++++++++++++ libraries/gpu/src/gpu/State.h | 2 +- 3 files changed, 148 insertions(+), 2 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp index 3236fa05e7..8ad67d4d7e 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp @@ -44,7 +44,7 @@ const GLState::Commands makeResetStateCommands() { // and we have a 50/50 chance that State::DEFAULT is not yet initialized. // Since State::DEFAULT = State::Data() it is much easier to not use the actual State::DEFAULT // but another State::Data object with a default initialization. - const State::Data DEFAULT = State::Data(); + const State::Data& DEFAULT = State::DEFAULT; auto depthBiasCommand = std::make_shared(&GLBackend::do_setStateDepthBias, Vec2(DEFAULT.depthBias, DEFAULT.depthBiasSlopeScale)); diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index ebc81f14e9..2b6490a67a 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -30,6 +30,152 @@ class QImage; namespace gpu { +// +// GL Backend pointer storage mechanism +// One of the following three defines must be defined. +// GPU_POINTER_STORAGE_SHARED + +// The platonic ideal, use references to smart pointers. +// However, this produces artifacts because there are too many places in the code right now that +// create temporary values (undesirable smart pointer duplications) and then those temp variables +// get passed on and have their reference taken, and then invalidated +// GPU_POINTER_STORAGE_REF + +// Raw pointer manipulation. Seems more dangerous than the reference wrappers, +// but in practice, the danger of grabbing a reference to a temporary variable +// is causing issues +// GPU_POINTER_STORAGE_RAW + +#if defined(USE_GLES) +#define GPU_POINTER_STORAGE_SHARED +#else +#define GPU_POINTER_STORAGE_RAW +#endif + +#if defined(GPU_POINTER_STORAGE_SHARED) +template +static inline bool compare(const std::shared_ptr& a, const std::shared_ptr& b) { + return a == b; +} + +template +static inline T* acquire(const std::shared_ptr& pointer) { + return pointer.get(); +} + +template +static inline void reset(std::shared_ptr& pointer) { + return pointer.reset(); +} + +template +static inline bool valid(const std::shared_ptr& pointer) { + return pointer.operator bool(); +} + +template +static inline void assign(std::shared_ptr& pointer, const std::shared_ptr& source) { + pointer = source; +} + +using BufferReference = BufferPointer; +using TextureReference = TexturePointer; +using FramebufferReference = FramebufferPointer; +using FormatReference = Stream::FormatPointer; +using PipelineReference = PipelinePointer; + +#define GPU_REFERENCE_INIT_VALUE nullptr + +#elif defined(GPU_POINTER_STORAGE_REF) + +template +class PointerReferenceWrapper : public std::reference_wrapper> { + using Parent = std::reference_wrapper>; + +public: + using Pointer = std::shared_ptr; + PointerReferenceWrapper() : Parent(EMPTY()) {} + PointerReferenceWrapper(const Pointer& pointer) : Parent(pointer) {} + void clear() { *this = EMPTY(); } + +private: + static const Pointer& EMPTY() { + static const Pointer EMPTY_VALUE; + return EMPTY_VALUE; + }; +}; + +template +static bool compare(const PointerReferenceWrapper& reference, const std::shared_ptr& pointer) { + return reference.get() == pointer; +} + +template +static inline T* acquire(const PointerReferenceWrapper& reference) { + return reference.get().get(); +} + +template +static void assign(PointerReferenceWrapper& reference, const std::shared_ptr& pointer) { + reference = pointer; +} + +template +static bool valid(const PointerReferenceWrapper& reference) { + return reference.get().operator bool(); +} + +template +static inline void reset(PointerReferenceWrapper& reference) { + return reference.clear(); +} + +using BufferReference = PointerReferenceWrapper; +using TextureReference = PointerReferenceWrapper; +using FramebufferReference = PointerReferenceWrapper; +using FormatReference = PointerReferenceWrapper; +using PipelineReference = PointerReferenceWrapper; + +#define GPU_REFERENCE_INIT_VALUE + +#elif defined(GPU_POINTER_STORAGE_RAW) + +template +static bool compare(const T* const& rawPointer, const std::shared_ptr& pointer) { + return rawPointer == pointer.get(); +} + +template +static inline T* acquire(T* const& rawPointer) { + return rawPointer; +} + +template +static inline bool valid(const T* const& rawPointer) { + return rawPointer; +} + +template +static inline void reset(T*& rawPointer) { + rawPointer = nullptr; +} + +template +static inline void assign(T*& rawPointer, const std::shared_ptr& pointer) { + rawPointer = pointer.get(); +} + +using BufferReference = Buffer*; +using TextureReference = Texture*; +using FramebufferReference = Framebuffer*; +using FormatReference = Stream::Format*; +using PipelineReference = Pipeline*; + +#define GPU_REFERENCE_INIT_VALUE nullptr + +#endif + + struct ContextStats { public: uint32_t _ISNumFormatChanges { 0 }; diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index 757169a138..1e165d899f 100644 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -274,7 +274,7 @@ public: struct Flags { Flags() : - frontFaceClockwise(false), depthClampEnable(false), scissorEnable(false), multisampleEnable(true), + frontFaceClockwise(false), depthClampEnable(false), scissorEnable(false), multisampleEnable(false), antialisedLineEnable(true), alphaToCoverageEnable(false) {} bool frontFaceClockwise; bool depthClampEnable;