From 169ca722b31c8492789b20bf42d4ea76a8e8e9d3 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 26 Oct 2018 11:53:52 -0400 Subject: [PATCH] Redesign vtkm::cont::ColorTable to work with separable compilation. --- benchmarking/BenchmarkRayTracing.cxx | 2 + vtkm/cont/CMakeLists.txt | 2 +- vtkm/cont/ColorTable.cxx | 135 ++++---------- vtkm/cont/ColorTable.h | 119 +++++++----- vtkm/cont/ColorTable.hxx | 262 ++++++++++++++++++++++++--- vtkm/cont/ColorTablePrivate.hxx | 77 -------- vtkm/rendering/Canvas.cxx | 2 + vtkm/rendering/CanvasGL.cxx | 2 + vtkm/rendering/Mapper.cxx | 2 + 9 files changed, 352 insertions(+), 251 deletions(-) diff --git a/benchmarking/BenchmarkRayTracing.cxx b/benchmarking/BenchmarkRayTracing.cxx index d0d201bf6..0f7b6490b 100644 --- a/benchmarking/BenchmarkRayTracing.cxx +++ b/benchmarking/BenchmarkRayTracing.cxx @@ -35,6 +35,8 @@ #include +#include + #include #include #include diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index ba2753ace..120856c5a 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -125,6 +125,7 @@ set(sources BoundsGlobalCompute.cxx CellSet.cxx CellSetStructured.cxx + ColorTable.cxx DataSet.cxx DataSetBuilderExplicit.cxx DataSetBuilderRectilinear.cxx @@ -154,7 +155,6 @@ set(sources set(device_sources ArrayRangeCompute.cxx CellSetExplicit.cxx - ColorTable.cxx CoordinateSystem.cxx ) diff --git a/vtkm/cont/ColorTable.cxx b/vtkm/cont/ColorTable.cxx index 50275bd37..65505f9ed 100644 --- a/vtkm/cont/ColorTable.cxx +++ b/vtkm/cont/ColorTable.cxx @@ -23,6 +23,9 @@ #include #include #include +#include +#include + namespace vtkm { @@ -44,7 +47,7 @@ ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset) if (!loaded) { //if we failed to load the requested color table, call SetColorSpace //so that the internal host side cache is constructed and we leave - //the constructor in a valid state. We use RGB as it is the default + //the constructor in a valid state. We use LAB as it is the default //when the no parameter constructor is called this->SetColorSpace(ColorSpace::LAB); } @@ -59,7 +62,7 @@ ColorTable::ColorTable(const std::string& name) if (!loaded) { //if we failed to load the requested color table, call SetColorSpace //so that the internal host side cache is constructed and we leave - //the constructor in a valid state. We use RGB as it is the default + //the constructor in a valid state. We use LAB as it is the default //when the no parameter constructor is called this->SetColorSpace(ColorSpace::LAB); } @@ -153,47 +156,42 @@ ColorSpace ColorTable::GetColorSpace() const //---------------------------------------------------------------------------- void ColorTable::SetColorSpace(ColorSpace space) { + if (this->Impl->CSpace != space || this->Impl->HostSideCache.get() == nullptr) { this->Impl->HostSideCacheChanged = true; this->Impl->CSpace = space; - //Remove any existing host and execution data + //Remove any existing host information - using HandleType = vtkm::cont::VirtualObjectHandle; switch (space) { case vtkm::cont::ColorSpace::RGB: { auto* hostPortal = new vtkm::exec::ColorTableRGB(); - this->Impl->ExecHandle.reset(new HandleType(hostPortal, false)); this->Impl->HostSideCache.reset(hostPortal); break; } case vtkm::cont::ColorSpace::HSV: { auto* hostPortal = new vtkm::exec::ColorTableHSV(); - this->Impl->ExecHandle.reset(new HandleType(hostPortal, false)); this->Impl->HostSideCache.reset(hostPortal); break; } case vtkm::cont::ColorSpace::HSV_WRAP: { auto* hostPortal = new vtkm::exec::ColorTableHSVWrap(); - this->Impl->ExecHandle.reset(new HandleType(hostPortal, false)); this->Impl->HostSideCache.reset(hostPortal); break; } case vtkm::cont::ColorSpace::LAB: { auto* hostPortal = new vtkm::exec::ColorTableLab(); - this->Impl->ExecHandle.reset(new HandleType(hostPortal, false)); this->Impl->HostSideCache.reset(hostPortal); break; } case vtkm::cont::ColorSpace::DIVERGING: { auto* hostPortal = new vtkm::exec::ColorTableDiverging(); - this->Impl->ExecHandle.reset(new HandleType(hostPortal, false)); this->Impl->HostSideCache.reset(hostPortal); break; } @@ -788,65 +786,32 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr this->Impl->OpacityArraysChanged = true; return true; } + //--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGBA& samples, - double tolerance) const +vtkm::Id ColorTable::GetModifiedCount() const { - if (numSamples <= 1) - { - return false; - } - samples.NumberOfSamples = numSamples; - samples.SampleRange = this->GetRange(); - return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); + return this->Impl->HostSideCache->GetModifiedCount(); } - -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGB& samples, - double tolerance) const +//---------------------------------------------------------------------------- +bool ColorTable::NeedToCreateExecutionColorTable() const { - if (numSamples <= 1) - { - return false; - } - samples.NumberOfSamples = numSamples; - samples.SampleRange = this->GetRange(); - return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); + return this->Impl->HostSideCacheChanged; } -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle>& colors, - double tolerance) const +//---------------------------------------------------------------------------- +void ColorTable::UpdateExecutionColorTable( + vtkm::cont::VirtualObjectHandle* handle) const { - if (numSamples <= 1) - { - return false; - } - return sampleColorTable(this, numSamples, colors, tolerance, false); + this->Impl->ExecHandle.reset(handle); } -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle>& colors, - double tolerance) const -{ - if (numSamples <= 1) - { - return false; - } - return sampleColorTable(this, numSamples, colors, tolerance, false); -} - -//--------------------------------------------------------------------------- -const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution( - vtkm::cont::DeviceAdapterId deviceId) const +//---------------------------------------------------------------------------- +ColorTable::TransferState ColorTable::GetExecutionDataForTransfer() const { //Only rebuild the array handles that have changed since the last time //we have modified or color / opacity information + if (this->Impl->ColorArraysChanged) { this->Impl->ColorPosHandle = vtkm::cont::make_ArrayHandle(this->Impl->ColorNodePos); @@ -860,56 +825,32 @@ const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution( this->Impl->OpacityMidSharpHandle = vtkm::cont::make_ArrayHandle(this->Impl->OpacityMidSharp); } - bool transfered = true; - if (this->Impl->ColorArraysChanged || this->Impl->OpacityArraysChanged || - this->Impl->HostSideCacheChanged) - { - transfered = vtkm::cont::TryExecuteOnDevice(deviceId, - detail::transfer_color_table_to_device{}, - this->Impl->HostSideCache.get(), - this->Impl.get()); - } - if (!transfered) - { - throwFailedRuntimeDeviceTransfer("ColorTable", deviceId); - } - + TransferState state = { (this->Impl->ColorArraysChanged || this->Impl->OpacityArraysChanged || + this->Impl->HostSideCacheChanged), + this->Impl->HostSideCache.get(), + this->Impl->ColorPosHandle, + this->Impl->ColorRGBHandle, + this->Impl->OpacityPosHandle, + this->Impl->OpacityAlphaHandle, + this->Impl->OpacityMidSharpHandle }; this->Impl->ColorArraysChanged = false; this->Impl->OpacityArraysChanged = false; this->Impl->HostSideCacheChanged = false; - return this->Impl->ExecHandle->PrepareForExecution(deviceId); + return state; } -//--------------------------------------------------------------------------- -vtkm::Id ColorTable::GetModifiedCount() const +//---------------------------------------------------------------------------- +vtkm::exec::ColorTableBase* ColorTable::GetControlRepresentation() const { - return this->Impl->HostSideCache->GetModifiedCount(); + return this->Impl->HostSideCache.get(); } - -/* -#define ColorTableExportMapFunctions(T) \ - template VTKM_CONT_EXPORT bool ColorTable::Map( \ - const vtkm::cont::ArrayHandle&, \ - const vtkm::cont::ColorTableSamplesRGBA&, \ - vtkm::cont::ArrayHandle>&) const; \ - template VTKM_CONT_EXPORT bool ColorTable::Map( \ - const vtkm::cont::ArrayHandle&, \ - const vtkm::cont::ColorTableSamplesRGB&, \ - vtkm::cont::ArrayHandle>&) const; \ - template VTKM_CONT_EXPORT bool ColorTable::Map( \ - const vtkm::cont::ArrayHandle&, \ - vtkm::cont::ArrayHandle>&) const; \ - template VTKM_CONT_EXPORT bool ColorTable::Map( \ - const vtkm::cont::ArrayHandle&, \ - vtkm::cont::ArrayHandle>&) const; -ColorTableExportMapFunctions(char); -ColorTableExportMapFunctions(vtkm::UInt8); -ColorTableExportMapFunctions(vtkm::Int8); -ColorTableExportMapFunctions(vtkm::Float32); -ColorTableExportMapFunctions(vtkm::Float64); -#undef ColorTableExportMapFunctions -*/ +//---------------------------------------------------------------------------- +vtkm::cont::VirtualObjectHandle const* ColorTable::GetExecutionHandle() + const +{ + return this->Impl->ExecHandle.get(); +} } } //namespace vtkm::cont diff --git a/vtkm/cont/ColorTable.h b/vtkm/cont/ColorTable.h index 23cd57cdb..c9af4a2d4 100644 --- a/vtkm/cont/ColorTable.h +++ b/vtkm/cont/ColorTable.h @@ -497,9 +497,9 @@ public: /// /// \endcode template - bool Map(const vtkm::cont::ArrayHandle& values, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool Map(const vtkm::cont::ArrayHandle& values, + const vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors /// @@ -518,39 +518,39 @@ public: /// /// \endcode template - bool Map(const vtkm::cont::ArrayHandle& values, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool Map(const vtkm::cont::ArrayHandle& values, + const vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Use magnitude of a vector with a sample table to generate RGBA colors /// template - bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + const vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Use magnitude of a vector with a sample table to generate RGB colors /// template - bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + const vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Use a single component of a vector with a sample table to generate RGBA colors /// template - bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + const vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Use a single component of a vector with a sample table to generate RGB colors /// template - bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle>& rgbOut) const; + inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + const vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::cont::ArrayHandle>& rgbOut) const; /// \brief Interpolate each value through the color table to generate RGBA colors @@ -560,8 +560,8 @@ public: /// /// Note: This is more costly than using Sample/Map with the generated intermediate lookup table template - bool Map(const vtkm::cont::ArrayHandle& values, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool Map(const vtkm::cont::ArrayHandle& values, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Interpolate each value through the color table to generate RGB colors /// @@ -570,34 +570,34 @@ public: /// /// Note: This is more costly than using Sample/Map with the generated intermediate lookup table template - bool Map(const vtkm::cont::ArrayHandle& values, - vtkm::cont::ArrayHandle>& rgbOut) const; + inline bool Map(const vtkm::cont::ArrayHandle& values, + vtkm::cont::ArrayHandle>& rgbOut) const; /// \brief Use magnitude of a vector to generate RGBA colors /// template - bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Use magnitude of a vector to generate RGB colors /// template - bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - vtkm::cont::ArrayHandle>& rgbOut) const; + inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + vtkm::cont::ArrayHandle>& rgbOut) const; /// \brief Use a single component of a vector to generate RGBA colors /// template - bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - vtkm::cont::ArrayHandle>& rgbaOut) const; + inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + vtkm::cont::ArrayHandle>& rgbaOut) const; /// \brief Use a single component of a vector to generate RGB colors /// template - bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - vtkm::cont::ArrayHandle>& rgbOut) const; + inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + vtkm::cont::ArrayHandle>& rgbOut) const; /// \brief generate RGB colors using regular spaced samples along the range. @@ -611,9 +611,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGBA& samples, - double tolerance = 0.002) const; + inline bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGBA& samples, + double tolerance = 0.002) const; /// \brief generate a sample lookup table using regular spaced samples along the range. /// @@ -626,9 +626,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGB& samples, - double tolerance = 0.002) const; + inline bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGB& samples, + double tolerance = 0.002) const; /// \brief generate RGBA colors using regular spaced samples along the range. /// @@ -641,9 +641,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle>& colors, - double tolerance = 0.002) const; + inline bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle>& colors, + double tolerance = 0.002) const; /// \brief generate RGB colors using regular spaced samples along the range. /// @@ -656,21 +656,46 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle>& colors, - double tolerance = 0.002) const; + inline bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle>& colors, + double tolerance = 0.002) const; /// \brief returns a virtual object pointer of the exec color table /// /// This pointer is only valid as long as the ColorTable is unmodified - const vtkm::exec::ColorTableBase* PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId) const; + inline const vtkm::exec::ColorTableBase* PrepareForExecution( + vtkm::cont::DeviceAdapterId deviceId) const; /// \brief returns the modified count for the virtual object handle of the exec color table /// /// The modified count allows consumers of a shared color table to keep track /// if the color table has been modified since the last time they used it. vtkm::Id GetModifiedCount() const; + + struct TransferState + { + bool NeedsTransfer; + vtkm::exec::ColorTableBase* Portal; + const vtkm::cont::ArrayHandle& ColorPosHandle; + const vtkm::cont::ArrayHandle>& ColorRGBHandle; + const vtkm::cont::ArrayHandle& OpacityPosHandle; + const vtkm::cont::ArrayHandle& OpacityAlphaHandle; + const vtkm::cont::ArrayHandle>& OpacityMidSharpHandle; + }; + +private: + bool NeedToCreateExecutionColorTable() const; + + //takes ownership of the pointer passed in + void UpdateExecutionColorTable( + vtkm::cont::VirtualObjectHandle*) const; + + ColorTable::TransferState GetExecutionDataForTransfer() const; + + vtkm::exec::ColorTableBase* GetControlRepresentation() const; + + vtkm::cont::VirtualObjectHandle const* GetExecutionHandle() const; }; } } //namespace vtkm::cont diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx index 77388b10e..e9fe3d8d4 100644 --- a/vtkm/cont/ColorTable.hxx +++ b/vtkm/cont/ColorTable.hxx @@ -17,6 +17,10 @@ // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ + +#ifndef vtk_m_cont_ColorTable_hxx +#define vtk_m_cont_ColorTable_hxx + #include #include #include @@ -50,44 +54,43 @@ inline T* get_ptr(stdext::checked_array_iterator t) } #endif -struct map_color_table -{ - template - bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const - { - vtkm::worklet::colorconversion::TransferFunction transfer(colors->PrepareForExecution(device)); - vtkm::worklet::Invoker invoke(device); - invoke(transfer, std::forward(args)...); - return true; - } -}; - struct transfer_color_table_to_device { - template - bool operator()(DeviceAdapter device, - vtkm::exec::ColorTableBase* portal, - ColorTableInternals* internals) const + template + inline bool operator()(DeviceAdapter device, vtkm::cont::ColorTable::TransferState&& state) const { - auto p1 = internals->ColorPosHandle.PrepareForInput(device); - auto p2 = internals->ColorRGBHandle.PrepareForInput(device); - auto p3 = internals->OpacityPosHandle.PrepareForInput(device); - auto p4 = internals->OpacityAlphaHandle.PrepareForInput(device); - auto p5 = internals->OpacityMidSharpHandle.PrepareForInput(device); + auto p1 = state.ColorPosHandle.PrepareForInput(device); + auto p2 = state.ColorRGBHandle.PrepareForInput(device); + auto p3 = state.OpacityPosHandle.PrepareForInput(device); + auto p4 = state.OpacityAlphaHandle.PrepareForInput(device); + auto p5 = state.OpacityMidSharpHandle.PrepareForInput(device); //The rest of the data member on portal are set when-ever the user //modifies the ColorTable instance and don't need to specified here - portal->ColorSize = static_cast(internals->ColorPosHandle.GetNumberOfValues()); - portal->OpacitySize = static_cast(internals->OpacityPosHandle.GetNumberOfValues()); + state.Portal->ColorSize = static_cast(state.ColorPosHandle.GetNumberOfValues()); + state.Portal->OpacitySize = + static_cast(state.OpacityPosHandle.GetNumberOfValues()); - portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1)); - portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2)); - portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3)); - portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4)); - portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5)); - portal->Modified(); + state.Portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1)); + state.Portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2)); + state.Portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3)); + state.Portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4)); + state.Portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5)); + state.Portal->Modified(); + return true; + } +}; + +struct map_color_table +{ + template + inline bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const + { + vtkm::worklet::colorconversion::TransferFunction transfer(colors->PrepareForExecution(device)); + vtkm::worklet::Invoker invoke(device); + invoke(transfer, std::forward(args)...); return true; } }; @@ -215,5 +218,206 @@ bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle, S>& using namespace vtkm::worklet::colorconversion; return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbOut); } + +namespace +{ + +template +inline vtkm::cont::ArrayHandle buildSampleHandle(vtkm::Int32 numSamples, + T start, + T end, + T inc, + bool appendNanAndRangeColors) +{ + + //number of samples + end + appendNanAndRangeColors + vtkm::Int32 allocationSize = (appendNanAndRangeColors) ? numSamples + 5 : numSamples + 1; + + vtkm::cont::ArrayHandle handle; + handle.Allocate(allocationSize); + + auto portal = handle.GetPortalControl(); + vtkm::Id index = 0; + + //Insert the below range first + if (appendNanAndRangeColors) + { + portal.Set(index++, std::numeric_limits::lowest()); //below + } + + //add number of samples which doesn't account for the end + T value = start; + for (vtkm::Int32 i = 0; i < numSamples; ++i, ++index, value += inc) + { + portal.Set(index, value); + } + portal.Set(index++, end); + + if (appendNanAndRangeColors) + { + //push back the last value again so that when lookups near the max value + //occur we don't need to clamp as if they are out-of-bounds they will + //land in the extra 'end' color + portal.Set(index++, end); + portal.Set(index++, std::numeric_limits::max()); //above + portal.Set(index++, vtkm::Nan()); //nan + } + + return handle; +} + +template +inline bool sampleColorTable(const ColorTable* self, + vtkm::Int32 numSamples, + OutputColors& colors, + double tolerance, + bool appendNanAndRangeColors) +{ + vtkm::Range r = self->GetRange(); + //We want the samples to start at Min, and end at Max so that means + //we want actually to interpolate numSample - 1 values. For example + //for range 0 - 1, we want the values 0, 0.5, and 1. + const double d_samples = static_cast(numSamples - 1); + const double d_delta = r.Length() / d_samples; + + if (r.Min > static_cast(std::numeric_limits::lowest()) && + r.Max < static_cast(std::numeric_limits::max())) + { + //we can try and see if float space has enough resolution + const float f_samples = static_cast(numSamples - 1); + const float f_start = static_cast(r.Min); + const float f_delta = static_cast(r.Length()) / f_samples; + const float f_end = f_start + (f_delta * f_samples); + + if (vtkm::Abs(static_cast(f_end) - r.Max) <= tolerance && + vtkm::Abs(static_cast(f_delta) - d_delta) <= tolerance) + { + auto handle = + buildSampleHandle((numSamples - 1), f_start, f_end, f_delta, appendNanAndRangeColors); + return self->Map(handle, colors); + } + } + + //otherwise we need to use double space + auto handle = buildSampleHandle((numSamples - 1), r.Min, r.Max, d_delta, appendNanAndRangeColors); + return self->Map(handle, colors); } } + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGBA& samples, + double tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + samples.NumberOfSamples = numSamples; + samples.SampleRange = this->GetRange(); + return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); +} + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGB& samples, + double tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + samples.NumberOfSamples = numSamples; + samples.SampleRange = this->GetRange(); + return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); +} + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle>& colors, + double tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + return sampleColorTable(this, numSamples, colors, tolerance, false); +} + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle>& colors, + double tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + return sampleColorTable(this, numSamples, colors, tolerance, false); +} + +//--------------------------------------------------------------------------- +const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution( + vtkm::cont::DeviceAdapterId device) const +{ + //Build the ColorTable instance that is needed for execution + if (this->NeedToCreateExecutionColorTable()) + { + auto space = this->GetColorSpace(); + auto hostPortal = this->GetControlRepresentation(); + //Remove any existing host and execution data. The allocation of the + //virtual object handle needs to occur in the .hxx so that it happens + //in the same library as the user and will be a valid virtual object + using HandleType = vtkm::cont::VirtualObjectHandle; + switch (space) + { + case vtkm::cont::ColorSpace::RGB: + { + this->UpdateExecutionColorTable( + new HandleType(static_cast(hostPortal), false)); + break; + } + case vtkm::cont::ColorSpace::HSV: + { + this->UpdateExecutionColorTable( + new HandleType(static_cast(hostPortal), false)); + break; + } + case vtkm::cont::ColorSpace::HSV_WRAP: + { + this->UpdateExecutionColorTable( + new HandleType(static_cast(hostPortal), false)); + break; + } + case vtkm::cont::ColorSpace::LAB: + { + this->UpdateExecutionColorTable( + new HandleType(static_cast(hostPortal), false)); + break; + } + case vtkm::cont::ColorSpace::DIVERGING: + { + this->UpdateExecutionColorTable( + new HandleType(static_cast(hostPortal), false)); + break; + } + } + } + + + //transfer ColorTable and all related data + auto&& info = this->GetExecutionDataForTransfer(); + if (info.NeedsTransfer) + { + bool transfered = vtkm::cont::TryExecuteOnDevice( + device, detail::transfer_color_table_to_device{}, std::move(info)); + if (!transfered) + { + throwFailedRuntimeDeviceTransfer("ColorTable", device); + } + } + return this->GetExecutionHandle()->PrepareForExecution(device); +} +} +} +#endif diff --git a/vtkm/cont/ColorTablePrivate.hxx b/vtkm/cont/ColorTablePrivate.hxx index d6bf1677f..19cd30d31 100644 --- a/vtkm/cont/ColorTablePrivate.hxx +++ b/vtkm/cont/ColorTablePrivate.hxx @@ -214,83 +214,6 @@ inline vtkm::Range adjustRange(const vtkm::Range& r) } -template -inline vtkm::cont::ArrayHandle buildSampleHandle(std::vector& samples, - vtkm::Int32 numSamples, - T start, - T end, - T inc, - bool appendNanAndRangeColors) -{ - int extra_values = (appendNanAndRangeColors) ? 0 : 4; - samples.reserve(static_cast(numSamples + extra_values)); - - //Insert the below range first - if (appendNanAndRangeColors) - { - samples.push_back(std::numeric_limits::lowest()); //below - } - - for (T i = start; i < end; i += inc) - { - samples.push_back(i); - } - samples.push_back(end); - - if (appendNanAndRangeColors) - { - //push back the last value again so that when lookups near the max value - //occur we can - samples.push_back(end); - samples.push_back(std::numeric_limits::max()); //above - samples.push_back(vtkm::Nan()); //nan - } - - return vtkm::cont::make_ArrayHandle(samples); -} - -template -inline bool sampleColorTable(const ColorTable* self, - vtkm::Int32 numSamples, - OutputColors& colors, - double tolerance, - bool appendNanAndRangeColors) -{ - vtkm::Range r = self->GetRange(); - //We want the samples to start at Min, and end at Max so that means - //we want actually to interpolate numSample - 1 values. For example - //for range 0 - 1, we want the values 0, 0.5, and 1. - const double d_samples = static_cast(numSamples - 1); - const double d_delta = r.Length() / d_samples; - - if (r.Min > static_cast(std::numeric_limits::lowest()) && - r.Max < static_cast(std::numeric_limits::max())) - { - //we can try and see if float space has enough resolution - const float f_samples = static_cast(numSamples - 1); - const float f_start = static_cast(r.Min); - const float f_delta = static_cast(r.Length()) / f_samples; - const float f_end = f_delta * f_samples; - - if (vtkm::Abs(static_cast(f_end) - r.Max) <= tolerance && - vtkm::Abs(static_cast(f_delta) - d_delta) <= tolerance) - { - std::vector samples; - auto handle = - buildSampleHandle(samples, numSamples, f_start, f_end, f_delta, appendNanAndRangeColors); - return self->Map(handle, colors); - } - } - - //otherwise we need to use double space - - std::vector samples; - auto handle = - buildSampleHandle(samples, numSamples, r.Min, r.Max, d_delta, appendNanAndRangeColors); - return self->Map(handle, colors); -} - - inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) { vtkm::Vec rgb; diff --git a/vtkm/rendering/Canvas.cxx b/vtkm/rendering/Canvas.cxx index 4d0c00a4f..c51f50a67 100644 --- a/vtkm/rendering/Canvas.cxx +++ b/vtkm/rendering/Canvas.cxx @@ -30,6 +30,8 @@ #include #include +#include + #include #include diff --git a/vtkm/rendering/CanvasGL.cxx b/vtkm/rendering/CanvasGL.cxx index 9005a5509..def2261c7 100644 --- a/vtkm/rendering/CanvasGL.cxx +++ b/vtkm/rendering/CanvasGL.cxx @@ -29,6 +29,8 @@ #include #include +#include + namespace vtkm { namespace rendering diff --git a/vtkm/rendering/Mapper.cxx b/vtkm/rendering/Mapper.cxx index ba6c4f159..2f0f1b245 100644 --- a/vtkm/rendering/Mapper.cxx +++ b/vtkm/rendering/Mapper.cxx @@ -20,6 +20,8 @@ #include +#include + namespace vtkm { namespace rendering