diff --git a/src/include/OpenImageIO/imagebuf.h b/src/include/OpenImageIO/imagebuf.h index 61946a17a4..c3f4402bc3 100644 --- a/src/include/OpenImageIO/imagebuf.h +++ b/src/include/OpenImageIO/imagebuf.h @@ -25,10 +25,7 @@ OIIO_NAMESPACE_BEGIN class ImageBuf; class ImageBufImpl; // Opaque type for the unique_ptr. class ImageCache; - -namespace pvt { class ImageCacheTile; -}; // namespace pvt @@ -1369,7 +1366,7 @@ class OIIO_API ImageBuf { int m_rng_xbegin, m_rng_xend, m_rng_ybegin, m_rng_yend, m_rng_zbegin, m_rng_zend; int m_x, m_y, m_z; - pvt::ImageCacheTile* m_tile = nullptr; + ImageCacheTile* m_tile = nullptr; int m_tilexbegin, m_tileybegin, m_tilezbegin; int m_tilexend; int m_nchannels; @@ -1638,7 +1635,7 @@ class OIIO_API ImageBuf { // tile for the given pixel, and return the ptr to the actual pixel // within the tile. If any read errors occur, set haderror=true (but // if there are no errors, do not modify haderror). - const void* retile(int x, int y, int z, pvt::ImageCacheTile*& tile, + const void* retile(int x, int y, int z, ImageCacheTile*& tile, int& tilexbegin, int& tileybegin, int& tilezbegin, int& tilexend, bool& haderr, bool exists, WrapMode wrap) const; diff --git a/src/include/OpenImageIO/imagecache.h b/src/include/OpenImageIO/imagecache.h index 63ff62c491..54671c5926 100644 --- a/src/include/OpenImageIO/imagecache.h +++ b/src/include/OpenImageIO/imagecache.h @@ -2,10 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 // https://github.com/AcademySoftwareFoundation/OpenImageIO -// clang-format off - - - #pragma once #include @@ -31,16 +27,13 @@ OIIO_NAMESPACE_BEGIN -// Forward declaration +// Forward declarations class TextureOpt; -namespace pvt { -// Forward declaration -class ImageCacheImpl; +class ImageCachePerThreadInfo; class ImageCacheFile; class ImageCacheTile; -class ImageCachePerThreadInfo; -}; // namespace pvt +class ImageCacheImpl; @@ -89,7 +82,8 @@ class OIIO_API ImageCache { /// nobody else is still holding a reference (otherwise, it will /// leave it intact). This parameter has no effect if `cache` was /// not the single globally shared ImageCache. - static void destroy(std::shared_ptr& cache, bool teardown = false); + static void destroy(std::shared_ptr& cache, + bool teardown = false); /// @} @@ -354,16 +348,30 @@ class OIIO_API ImageCache { /// (including it being an unrecognized attribute or not /// of the correct type). /// - virtual bool attribute (string_view name, TypeDesc type, - const void *val) = 0; + bool attribute(string_view name, TypeDesc type, const void* val); /// Specialized `attribute()` for setting a single `int` value. - virtual bool attribute (string_view name, int val) = 0; + bool attribute(string_view name, int val) + { + return attribute(name, TypeInt, &val); + } /// Specialized `attribute()` for setting a single `float` value. - virtual bool attribute (string_view name, float val) = 0; - virtual bool attribute (string_view name, double val) = 0; + bool attribute(string_view name, float val) + { + return attribute(name, TypeFloat, &val); + } + bool attribute(string_view name, double val) + { + float f = (float)val; + return attribute(name, TypeFloat, &f); + } /// Specialized `attribute()` for setting a single string value. - virtual bool attribute (string_view name, string_view val) = 0; + bool attribute(string_view name, string_view val) + { + std::string valstr(val); + const char* s = valstr.c_str(); + return attribute(name, TypeString, &s); + } /// Get the named attribute, store it in `*val`. All of the attributes /// that may be set with the `attribute() call` may also be queried with @@ -399,26 +407,48 @@ class OIIO_API ImageCache { /// attribute was retrieved, or `false` upon failure /// (including it being an unrecognized attribute or not /// of the correct type). - virtual bool getattribute (string_view name, TypeDesc type, - void *val) const = 0; + bool getattribute(string_view name, TypeDesc type, void* val) const; /// Specialized `attribute()` for retrieving a single `int` value. - virtual bool getattribute (string_view name, int &val) const = 0; + bool getattribute(string_view name, int& val) const + { + return getattribute(name, TypeInt, &val); + } /// Specialized `attribute()` for retrieving a single `float` value. - virtual bool getattribute (string_view name, float &val) const = 0; - virtual bool getattribute (string_view name, double &val) const = 0; + bool getattribute(string_view name, float& val) const + { + return getattribute(name, TypeFloat, &val); + } + bool getattribute(string_view name, double& val) const + { + float f; + bool ok = getattribute(name, TypeFloat, &f); + if (ok) + val = f; + return ok; + } /// Specialized `attribute()` for retrieving a single `string` value /// as a `char*`. - virtual bool getattribute (string_view name, char **val) const = 0; + bool getattribute(string_view name, char** val) const + { + return getattribute(name, TypeString, val); + } /// Specialized `attribute()` for retrieving a single `string` value /// as a `std::string`. - virtual bool getattribute (string_view name, std::string &val) const = 0; + bool getattribute(string_view name, std::string& val) const + { + ustring s; + bool ok = getattribute(name, TypeString, &s); + if (ok) + val = s.string(); + return ok; + } /// If the named attribute is known, return its data type. If no such /// attribute exists, return `TypeUnknown`. /// /// This was added in version 2.5. - virtual TypeDesc getattributetype(string_view name) const = 0; + TypeDesc getattributetype(string_view name) const; /// @} @@ -456,7 +486,7 @@ class OIIO_API ImageCache { /// Define an opaque data type that allows us to have a pointer to /// certain per-thread information that the ImageCache maintains. Any /// given one of these should NEVER be shared between running threads. - typedef pvt::ImageCachePerThreadInfo Perthread; + using Perthread = ImageCachePerThreadInfo; /// Retrieve a Perthread, unique to the calling thread. This is a /// thread-specific pointer that will always return the Perthread for a @@ -469,19 +499,19 @@ class OIIO_API ImageCache { /// thread_info is not NULL, it won't create a new one or retrieve a /// TSP, but it will do other necessary housekeeping on the Perthread /// information. - virtual Perthread* get_perthread_info(Perthread* thread_info = NULL) = 0; + Perthread* get_perthread_info(Perthread* thread_info = NULL); /// Create a new Perthread. It is the caller's responsibility to /// eventually destroy it using `destroy_thread_info()`. - virtual Perthread* create_thread_info() = 0; + Perthread* create_thread_info(); /// Destroy a Perthread that was allocated by `create_thread_info()`. - virtual void destroy_thread_info(Perthread* thread_info) = 0; + void destroy_thread_info(Perthread* thread_info); /// Define an opaque data type that allows us to have a handle to an /// image (already having its name resolved) but without exposing any /// internals. - typedef pvt::ImageCacheFile ImageHandle; + using ImageHandle = ImageCacheFile; /// Retrieve an opaque handle for fast texture lookups, or nullptr upon /// failure. The filename is presumed to be UTF-8 encoded. The `options`, @@ -489,26 +519,27 @@ class OIIO_API ImageCache { /// texture option choices. (Currently unused, but reserved for the future /// or for alternate IC implementations.) The opaque pointer `thread_info` /// is thread-specific information returned by `get_perthread_info()`. - virtual ImageHandle* get_image_handle(ustring filename, - Perthread* thread_info = nullptr, - const TextureOpt* options = nullptr) = 0; + ImageHandle* get_image_handle(ustring filename, + Perthread* thread_info = nullptr, + const TextureOpt* options = nullptr); /// Get an ImageHandle using a UTF-16 encoded wstring filename. ImageHandle* get_image_handle(const std::wstring& filename, - Perthread* thread_info = nullptr, - const TextureOpt* options = nullptr) { + Perthread* thread_info = nullptr, + const TextureOpt* options = nullptr) + { return get_image_handle(ustring(Strutil::utf16_to_utf8(filename)), thread_info, options); } /// Return true if the image handle (previously returned by /// `get_image_handle()`) is a valid image that can be subsequently read. - virtual bool good(ImageHandle* file) = 0; + bool good(ImageHandle* file); /// Given a handle, return the filename for that image. /// /// This method was added in OpenImageIO 2.3. - virtual ustring filename_from_handle(ImageHandle* handle) = 0; + ustring filename_from_handle(ImageHandle* handle); /// @} @@ -519,7 +550,7 @@ class OIIO_API ImageCache { /// Given possibly-relative `filename` (UTF-8 encoded), resolve it and use /// the true path to the file, with searchpath logic applied. - virtual std::string resolve_filename(const std::string& filename) const = 0; + std::string resolve_filename(const std::string& filename) const; /// Get information or metadata about the named image and store it in /// `*data`. @@ -684,14 +715,14 @@ class OIIO_API ImageCache { /// Except for the `"exists"` query, a file that does not /// exist or could not be read properly as an image also /// constitutes a query failure that will return `false`. - virtual bool get_image_info (ustring filename, int subimage, int miplevel, - ustring dataname, TypeDesc datatype, void *data) = 0; + bool get_image_info(ustring filename, int subimage, int miplevel, + ustring dataname, TypeDesc datatype, void* data); /// A more efficient variety of `get_image_info()` for cases where you /// can use an `ImageHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual bool get_image_info (ImageHandle *file, Perthread *thread_info, - int subimage, int miplevel, - ustring dataname, TypeDesc datatype, void *data) = 0; + bool get_image_info(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, ustring dataname, TypeDesc datatype, + void* data); /// Copy the ImageSpec associated with the named image (the first /// subimage & miplevel by default, or as set by `subimage` and @@ -716,16 +747,14 @@ class OIIO_API ImageCache { /// as being unable to find, open, or read the file, or if /// it does not contain the designated subimage or MIP /// level). - virtual bool get_imagespec (ustring filename, ImageSpec &spec, - int subimage=0, int miplevel=0, - bool native=false) = 0; + bool get_imagespec(ustring filename, ImageSpec& spec, int subimage = 0, + int miplevel = 0, bool native = false); /// A more efficient variety of `get_imagespec()` for cases where you /// can use an `ImageHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual bool get_imagespec (ImageHandle *file, Perthread *thread_info, - ImageSpec &spec, - int subimage=0, int miplevel=0, - bool native=false) = 0; + bool get_imagespec(ImageHandle* file, Perthread* thread_info, + ImageSpec& spec, int subimage = 0, int miplevel = 0, + bool native = false); /// Return a pointer to an ImageSpec associated with the named image /// (the first subimage & MIP level by default, or as set by `subimage` @@ -754,15 +783,14 @@ class OIIO_API ImageCache { /// A pointer to the spec, if the image is found and able to /// be opened and read by an available image format plugin, /// and the designated subimage and MIP level exists. - virtual const ImageSpec *imagespec (ustring filename, int subimage=0, - int miplevel=0, bool native=false) = 0; + const ImageSpec* imagespec(ustring filename, int subimage = 0, + int miplevel = 0, bool native = false); /// A more efficient variety of `imagespec()` for cases where you can /// use an `ImageHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual const ImageSpec *imagespec (ImageHandle *file, - Perthread *thread_info, - int subimage=0, int miplevel=0, - bool native=false) = 0; + const ImageSpec* imagespec(ImageHandle* file, Perthread* thread_info, + int subimage = 0, int miplevel = 0, + bool native = false); /// Copy into `thumbnail` any associated thumbnail associated with this /// image (for the first subimage by default, or as set by `subimage`). @@ -779,13 +807,12 @@ class OIIO_API ImageCache { /// `true` upon success, `false` upon failure failure (such /// as being unable to find, open, or read the file, or if /// it does not contain a thumbnail). - virtual bool get_thumbnail (ustring filename, ImageBuf& thumbnail, - int subimage=0) = 0; + bool get_thumbnail(ustring filename, ImageBuf& thumbnail, int subimage = 0); /// A more efficient variety of `get_thumbnail()` for cases where you /// can use an `ImageHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual bool get_thumbnail (ImageHandle *file, Perthread *thread_info, - ImageBuf& thumbnail, int subimage=0) = 0; + bool get_thumbnail(ImageHandle* file, Perthread* thread_info, + ImageBuf& thumbnail, int subimage = 0); /// @} /// @{ @@ -835,38 +862,36 @@ class OIIO_API ImageCache { /// /// @returns /// `true` for success, `false` for failure. - virtual bool get_pixels (ustring filename, - int subimage, int miplevel, int xbegin, int xend, - int ybegin, int yend, int zbegin, int zend, - int chbegin, int chend, TypeDesc format, void *result, - stride_t xstride=AutoStride, stride_t ystride=AutoStride, - stride_t zstride=AutoStride, - int cache_chbegin = 0, int cache_chend = -1) = 0; + bool get_pixels(ustring filename, int subimage, int miplevel, int xbegin, + int xend, int ybegin, int yend, int zbegin, int zend, + int chbegin, int chend, TypeDesc format, void* result, + stride_t xstride = AutoStride, + stride_t ystride = AutoStride, + stride_t zstride = AutoStride, int cache_chbegin = 0, + int cache_chend = -1); /// A more efficient variety of `get_pixels()` for cases where you can /// use an `ImageHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual bool get_pixels (ImageHandle *file, Perthread *thread_info, - int subimage, int miplevel, int xbegin, int xend, - int ybegin, int yend, int zbegin, int zend, - int chbegin, int chend, TypeDesc format, void *result, - stride_t xstride=AutoStride, stride_t ystride=AutoStride, - stride_t zstride=AutoStride, - int cache_chbegin = 0, int cache_chend = -1) = 0; + bool get_pixels(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, int xbegin, int xend, int ybegin, int yend, + int zbegin, int zend, int chbegin, int chend, + TypeDesc format, void* result, + stride_t xstride = AutoStride, + stride_t ystride = AutoStride, + stride_t zstride = AutoStride, int cache_chbegin = 0, + int cache_chend = -1); /// A simplified `get_pixels()` where all channels are retrieved, /// strides are assumed to be contiguous. - virtual bool get_pixels (ustring filename, int subimage, int miplevel, - int xbegin, int xend, int ybegin, int yend, - int zbegin, int zend, - TypeDesc format, void *result) = 0; + bool get_pixels(ustring filename, int subimage, int miplevel, int xbegin, + int xend, int ybegin, int yend, int zbegin, int zend, + TypeDesc format, void* result); /// A more efficient variety of `get_pixels()` for cases where you can /// use an `ImageHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual bool get_pixels (ImageHandle *file, Perthread *thread_info, - int subimage, int miplevel, - int xbegin, int xend, int ybegin, int yend, - int zbegin, int zend, - TypeDesc format, void *result) = 0; + bool get_pixels(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, int xbegin, int xend, int ybegin, int yend, + int zbegin, int zend, TypeDesc format, void* result); /// @} /// @{ @@ -886,11 +911,11 @@ class OIIO_API ImageCache { /// If `force` is true, this invalidation will happen unconditionally; if /// false, the file will only be invalidated if it has been changed since /// it was first opened by the ImageCache. - virtual void invalidate(ustring filename, bool force = true) = 0; + void invalidate(ustring filename, bool force = true); /// A more efficient variety of `invalidate()` for cases where you /// already have an `ImageHandle*` for the file you want to invalidate. - virtual void invalidate(ImageHandle* file, bool force = true) = 0; + void invalidate(ImageHandle* file, bool force = true); /// Invalidate all loaded tiles and close open file handles. This is /// safe to do even if other procedures are currently holding @@ -902,21 +927,21 @@ class OIIO_API ImageCache { /// wasteful it is, but if `force` is false, in actuality files will /// only be invalidated if their modification times have been changed /// since they were first opened. - virtual void invalidate_all(bool force = false) = 0; + void invalidate_all(bool force = false); /// Close any open file handles associated with a named file (UTF-8 /// encoded), but do not invalidate any image spec information or pixels /// associated with the files. A client might do this in order to release /// OS file handle resources, or to make it safe for other processes to /// modify image files on disk. - virtual void close (ustring filename) = 0; + void close(ustring filename); /// `close()` all files known to the cache. - virtual void close_all () = 0; + void close_all(); /// An opaque data type that allows us to have a pointer to a tile but /// without exposing any internals. - typedef pvt::ImageCacheTile Tile; + using Tile = ImageCacheTile; /// Find the tile specified by an image filename (UTF-8 encoded), subimage /// & miplevel, the coordinates of a pixel, and optionally a channel @@ -926,30 +951,28 @@ class OIIO_API ImageCache { /// called on the tile pointer the same number of times that `get_tile()` /// was called (reference counting). This is thread-safe! If `chend < /// chbegin`, it will retrieve a tile containing all channels in the file. - virtual Tile * get_tile (ustring filename, int subimage, int miplevel, - int x, int y, int z, - int chbegin = 0, int chend = -1) = 0; + Tile* get_tile(ustring filename, int subimage, int miplevel, int x, int y, + int z, int chbegin = 0, int chend = -1); /// A slightly more efficient variety of `get_tile()` for cases where /// you can use an `ImageHandle*` to specify the image and optionally /// have a `Perthread*` for the calling thread. /// /// @see `get_pixels()` - virtual Tile * get_tile (ImageHandle *file, Perthread *thread_info, - int subimage, int miplevel, - int x, int y, int z, - int chbegin = 0, int chend = -1) = 0; + Tile* get_tile(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, int x, int y, int z, int chbegin = 0, + int chend = -1); /// After finishing with a tile, release_tile will allow it to /// once again be purged from the tile cache if required. - virtual void release_tile(Tile* tile) const = 0; + void release_tile(Tile* tile) const; /// Retrieve the data type of the pixels stored in the tile, which may /// be different than the type of the pixels in the disk file. - virtual TypeDesc tile_format(const Tile* tile) const = 0; + TypeDesc tile_format(const Tile* tile) const; /// Retrieve the ROI describing the pixels and channels stored in the /// tile. - virtual ROI tile_roi(const Tile* tile) const = 0; + ROI tile_roi(const Tile* tile) const; /// For a tile retrieved by `get_tile()`, return a pointer to the pixel /// data itself, and also store in `format` the data type that the @@ -957,7 +980,7 @@ class OIIO_API ImageCache { /// data type of the pixels in the disk file). This method should only /// be called on a tile that has been requested by `get_tile()` but has /// not yet been released with `release_tile()`. - virtual const void* tile_pixels(Tile* tile, TypeDesc& format) const = 0; + const void* tile_pixels(Tile* tile, TypeDesc& format) const; /// The add_file() call causes a file to be opened or added to the /// cache. There is no reason to use this method unless you are @@ -989,9 +1012,8 @@ class OIIO_API ImageCache { /// ImageCache. But if replace is true, any existing entry will be /// invalidated, closed and overwritten. So any subsequent access will /// see the new file. Existing texture handles will still be valid. - virtual bool add_file (ustring filename, ImageInput::Creator creator=nullptr, - const ImageSpec *config=nullptr, - bool replace = false) = 0; + bool add_file(ustring filename, ImageInput::Creator creator = nullptr, + const ImageSpec* config = nullptr, bool replace = false); /// Preemptively add a tile corresponding to the named image, at the /// given subimage, MIP level, and channel range. The tile added is the @@ -1003,11 +1025,11 @@ class OIIO_API ImageCache { /// data is assumed to be in some kind of persistent storage and will /// not be copied, nor will its pixels take up additional memory in the /// cache. - virtual bool add_tile (ustring filename, int subimage, int miplevel, - int x, int y, int z, int chbegin, int chend, - TypeDesc format, const void *buffer, - stride_t xstride=AutoStride, stride_t ystride=AutoStride, - stride_t zstride=AutoStride, bool copy = true) = 0; + bool add_tile(ustring filename, int subimage, int miplevel, int x, int y, + int z, int chbegin, int chend, TypeDesc format, + const void* buffer, stride_t xstride = AutoStride, + stride_t ystride = AutoStride, stride_t zstride = AutoStride, + bool copy = true); /// @} @@ -1015,40 +1037,44 @@ class OIIO_API ImageCache { /// @name Errors and statistics /// Is there a pending error message waiting to be retrieved? - virtual bool has_error() const = 0; + bool has_error() const; /// Return the text of all pending error messages issued against this /// ImageCache, and clear the pending error message unless `clear` is /// false. If no error message is pending, it will return an empty /// string. - virtual std::string geterror(bool clear = true) const = 0; + std::string geterror(bool clear = true) const; /// Returns a big string containing useful statistics about the /// ImageCache operations, suitable for saving to a file or outputting /// to the terminal. The `level` indicates the amount of detail in /// the statistics, with higher numbers (up to a maximum of 5) yielding /// more and more esoteric information. - virtual std::string getstats(int level = 1) const = 0; + std::string getstats(int level = 1) const; /// Reset most statistics to be as they were with a fresh ImageCache. /// Caveat emptor: this does not flush the cache itelf, so the resulting /// statistics from the next set of texture requests will not match the /// number of tile reads, etc., that would have resulted from a new /// ImageCache. - virtual void reset_stats() = 0; + void reset_stats(); /// @} - virtual ~ImageCache() {} + ImageCache(); + ~ImageCache(); + +private: + friend class TextureSystem; + friend class TextureSystemImpl; + + // PIMPL idiom + using Impl = ImageCacheImpl; + static void impl_deleter(Impl*); + std::unique_ptr m_impl; -protected: // User code should never directly construct or destruct an ImageCache. // Always use ImageCache::create() and ImageCache::destroy(). - ImageCache(void) {} -private: - // Make delete private and unimplemented in order to prevent apps - // from calling it. Instead, they should call ImageCache::destroy(). - void operator delete(void* /*todel*/) {} }; diff --git a/src/include/OpenImageIO/texture.h b/src/include/OpenImageIO/texture.h index 43eba9a7f8..e64adaccd2 100644 --- a/src/include/OpenImageIO/texture.h +++ b/src/include/OpenImageIO/texture.h @@ -45,11 +45,11 @@ OIIO_NAMESPACE_BEGIN // Forward declarations class ImageCache; +class TextureSystemImpl; namespace pvt { -class TextureSystemImpl; // Used internally by TextureSystem. Unfortunately, this is the only // clean place to store it. Sorry, users, this isn't really for you. @@ -295,7 +295,7 @@ class OIIO_API TextureOpt { // Options set INTERNALLY by libtexture after the options are passed // by the user. Users should not attempt to alter these! int envlayout; // Layout for environment wrap - friend class pvt::TextureSystemImpl; + friend class TextureSystemImpl; }; @@ -347,10 +347,13 @@ class OIIO_API TextureOptBatch { // by the user. Users should not attempt to alter these! int envlayout = 0; // Layout for environment wrap - friend class pvt::TextureSystemImpl; + friend class TextureSystemImpl; }; +// clang-format on + + /// Define an API to an abstract class that that manages texture files, /// caches of open file handles as well as tiles of texels so that truly @@ -391,8 +394,8 @@ class OIIO_API TextureSystem { /// when the last shared_ptr to it is destroyed. /// /// @see TextureSystem::destroy - static std::shared_ptr create(bool shared=true, - std::shared_ptr imagecache = {}); + static std::shared_ptr + create(bool shared = true, std::shared_ptr imagecache = {}); /// Release the shared_ptr to a TextureSystem, including freeing all /// system resources that it holds if no one else is still using it. This @@ -566,15 +569,30 @@ class OIIO_API TextureSystem { /// (including it being an unrecognized attribute or not /// of the correct type). /// - virtual bool attribute (string_view name, TypeDesc type, const void *val) = 0; + bool attribute(string_view name, TypeDesc type, const void* val); /// Specialized `attribute()` for setting a single `int` value. - virtual bool attribute (string_view name, int val) = 0; + bool attribute(string_view name, int val) + { + return attribute(name, TypeInt, &val); + } /// Specialized `attribute()` for setting a single `float` value. - virtual bool attribute (string_view name, float val) = 0; - virtual bool attribute (string_view name, double val) = 0; + bool attribute(string_view name, float val) + { + return attribute(name, TypeFloat, &val); + } + bool attribute(string_view name, double val) + { + float f = (float)val; + return attribute(name, TypeFloat, &f); + } /// Specialized `attribute()` for setting a single string value. - virtual bool attribute (string_view name, string_view val) = 0; + bool attribute(string_view name, string_view val) + { + std::string valstr(val); + const char* s = valstr.c_str(); + return attribute(name, TypeDesc::STRING, &s); + } /// Get the named attribute of the texture system, store it in `*val`. /// All of the attributes that may be set with the `attribute() call` @@ -610,26 +628,48 @@ class OIIO_API TextureSystem { /// attribute was retrieved, or `false` upon failure /// (including it being an unrecognized attribute or not /// of the correct type). - virtual bool getattribute (string_view name, - TypeDesc type, void *val) const = 0; + bool getattribute(string_view name, TypeDesc type, void* val) const; /// Specialized `attribute()` for retrieving a single `int` value. - virtual bool getattribute(string_view name, int& val) const = 0; + bool getattribute(string_view name, int& val) const + { + return getattribute(name, TypeInt, &val); + } /// Specialized `attribute()` for retrieving a single `float` value. - virtual bool getattribute(string_view name, float& val) const = 0; - virtual bool getattribute(string_view name, double& val) const = 0; + bool getattribute(string_view name, float& val) const + { + return getattribute(name, TypeFloat, &val); + } + bool getattribute(string_view name, double& val) const + { + float f; + bool ok = getattribute(name, TypeFloat, &f); + if (ok) + val = f; + return ok; + } /// Specialized `attribute()` for retrieving a single `string` value /// as a `char*`. - virtual bool getattribute(string_view name, char** val) const = 0; + bool getattribute(string_view name, char** val) const + { + return getattribute(name, TypeString, val); + } /// Specialized `attribute()` for retrieving a single `string` value /// as a `std::string`. - virtual bool getattribute(string_view name, std::string& val) const = 0; + bool getattribute(string_view name, std::string& val) const + { + const char* s; + bool ok = getattribute(name, TypeString, &s); + if (ok) + val = s; + return ok; + } /// If the named attribute is known, return its data type. If no such /// attribute exists, return `TypeUnknown`. /// /// This was added in version 2.5. - virtual TypeDesc getattributetype (string_view name) const = 0; + TypeDesc getattributetype(string_view name) const; /// @} @@ -680,14 +720,14 @@ class OIIO_API TextureSystem { /// thread_info is not nullptr, it won't create a new one or retrieve a /// TSP, but it will do other necessary housekeeping on the Perthread /// information. - virtual Perthread* get_perthread_info(Perthread* thread_info = nullptr) = 0; + Perthread* get_perthread_info(Perthread* thread_info = nullptr); /// Create a new Perthread. It is the caller's responsibility to /// eventually destroy it using `destroy_thread_info()`. - virtual Perthread* create_thread_info() = 0; + Perthread* create_thread_info(); /// Destroy a Perthread that was allocated by `create_thread_info()`. - virtual void destroy_thread_info(Perthread* threadinfo) = 0; + void destroy_thread_info(Perthread* threadinfo); /// Define an opaque data type that allows us to have a handle to a /// texture (already having its name resolved) but without exposing @@ -700,13 +740,14 @@ class OIIO_API TextureSystem { /// (currently: the colorspace). The opaque pointer `thread_info` is /// thread-specific information returned by `get_perthread_info()`. Return /// nullptr if something has gone horribly wrong. - virtual TextureHandle* get_texture_handle(ustring filename, - Perthread* thread_info = nullptr, - const TextureOpt* options = nullptr) = 0; + TextureHandle* get_texture_handle(ustring filename, + Perthread* thread_info = nullptr, + const TextureOpt* options = nullptr); /// Get a TextureHandle using a UTF-16 encoded wstring filename. TextureHandle* get_texture_handle(const std::wstring& filename, - Perthread* thread_info = nullptr, - const TextureOpt* options = nullptr) { + Perthread* thread_info = nullptr, + const TextureOpt* options = nullptr) + { return get_texture_handle(ustring(Strutil::utf16_to_utf8(filename)), thread_info, options); } @@ -714,21 +755,19 @@ class OIIO_API TextureSystem { /// Return true if the texture handle (previously returned by /// `get_image_handle()`) is a valid texture that can be subsequently /// read. - virtual bool good(TextureHandle* texture_handle) = 0; + bool good(TextureHandle* texture_handle); /// Given a handle, return the UTF-8 encoded filename for that texture. /// /// This method was added in OpenImageIO 2.3. - virtual ustring filename_from_handle(TextureHandle* handle) = 0; + ustring filename_from_handle(TextureHandle* handle); /// Retrieve an id for a color transformation by name. This ID can be used /// as the value for TextureOpt::colortransformid. The returned value will /// be -1 if either color space is unknown, and 0 for a null /// transformation. - virtual int get_colortransform_id(ustring fromspace, - ustring tospace) const = 0; - virtual int get_colortransform_id(ustringhash fromspace, - ustringhash tospace) const = 0; + int get_colortransform_id(ustring fromspace, ustring tospace) const; + int get_colortransform_id(ustringhash fromspace, ustringhash tospace) const; /// @} /// @{ @@ -812,20 +851,17 @@ class OIIO_API TextureSystem { /// found or could not be opened by any available ImageIO /// plugin. /// - virtual bool texture (ustring filename, TextureOpt &options, - float s, float t, float dsdx, float dtdx, - float dsdy, float dtdy, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool texture(ustring filename, TextureOpt& options, float s, float t, + float dsdx, float dtdx, float dsdy, float dtdy, int nchannels, + float* result, float* dresultds = nullptr, + float* dresultdt = nullptr); /// Slightly faster version of texture() lookup if the app already has a /// texture handle and per-thread info. - virtual bool texture (TextureHandle *texture_handle, - Perthread *thread_info, TextureOpt &options, - float s, float t, float dsdx, float dtdx, - float dsdy, float dtdy, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool texture(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, float s, float t, float dsdx, float dtdx, + float dsdy, float dtdy, int nchannels, float* result, + float* dresultds = nullptr, float* dresultdt = nullptr); /// Perform a filtered 3D volumetric texture lookup on a position @@ -907,40 +943,19 @@ class OIIO_API TextureSystem { /// found or could not be opened by any available ImageIO /// plugin. /// - virtual bool texture3d (ustring filename, TextureOpt &options, - V3fParam P, V3fParam dPdx, - V3fParam dPdy, V3fParam dPdz, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr, - float *dresultdr=nullptr) = 0; + bool texture3d(ustring filename, TextureOpt& options, V3fParam P, + V3fParam dPdx, V3fParam dPdy, V3fParam dPdz, int nchannels, + float* result, float* dresultds = nullptr, + float* dresultdt = nullptr, float* dresultdr = nullptr); /// Slightly faster version of texture3d() lookup if the app already has /// a texture handle and per-thread info. - virtual bool texture3d (TextureHandle *texture_handle, - Perthread *thread_info, TextureOpt &options, - V3fParam P, V3fParam dPdx, - V3fParam dPdy, V3fParam dPdz, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr, - float *dresultdr=nullptr) = 0; - - - // Retrieve a shadow lookup for a single position P. - // - // Return true if the file is found and could be opened by an - // available ImageIO plugin, otherwise return false. - virtual bool shadow (ustring filename, TextureOpt &options, - V3fParam P, V3fParam dPdx, - V3fParam dPdy, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; - - // Slightly faster version of texture3d() lookup if the app already - // has a texture handle and per-thread info. - virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info, - TextureOpt &options, - V3fParam P, V3fParam dPdx, - V3fParam dPdy, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool texture3d(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, V3fParam P, V3fParam dPdx, + V3fParam dPdy, V3fParam dPdz, int nchannels, float* result, + float* dresultds = nullptr, float* dresultdt = nullptr, + float* dresultdr = nullptr); + /// Perform a filtered directional environment map lookup in the /// direction of vector `R`, from the texture identified by `filename`, @@ -998,18 +1013,16 @@ class OIIO_API TextureSystem { /// `true` upon success, or `false` if the file was not /// found or could not be opened by any available ImageIO /// plugin. - virtual bool environment (ustring filename, TextureOpt &options, - V3fParam R, V3fParam dRdx, - V3fParam dRdy, int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool environment(ustring filename, TextureOpt& options, V3fParam R, + V3fParam dRdx, V3fParam dRdy, int nchannels, float* result, + float* dresultds = nullptr, float* dresultdt = nullptr); /// Slightly faster version of environment() if the app already has a /// texture handle and per-thread info. - virtual bool environment (TextureHandle *texture_handle, - Perthread *thread_info, TextureOpt &options, - V3fParam R, V3fParam dRdx, - V3fParam dRdy, int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool environment(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, V3fParam R, V3fParam dRdx, + V3fParam dRdy, int nchannels, float* result, + float* dresultds = nullptr, float* dresultdt = nullptr); /// @} @@ -1063,23 +1076,19 @@ class OIIO_API TextureSystem { /// found or could not be opened by any available ImageIO /// plugin. /// - virtual bool texture (ustring filename, TextureOptBatch &options, - Tex::RunMask mask, const float *s, const float *t, - const float *dsdx, const float *dtdx, - const float *dsdy, const float *dtdy, - int nchannels, float *result, - float *dresultds=nullptr, - float *dresultdt=nullptr) = 0; + bool texture(ustring filename, TextureOptBatch& options, Tex::RunMask mask, + const float* s, const float* t, const float* dsdx, + const float* dtdx, const float* dsdy, const float* dtdy, + int nchannels, float* result, float* dresultds = nullptr, + float* dresultdt = nullptr); /// Slightly faster version of texture() lookup if the app already has a /// texture handle and per-thread info. - virtual bool texture (TextureHandle *texture_handle, - Perthread *thread_info, TextureOptBatch &options, - Tex::RunMask mask, const float *s, const float *t, - const float *dsdx, const float *dtdx, - const float *dsdy, const float *dtdy, - int nchannels, float *result, - float *dresultds=nullptr, - float *dresultdt=nullptr) = 0; + bool texture(TextureHandle* texture_handle, Perthread* thread_info, + TextureOptBatch& options, Tex::RunMask mask, const float* s, + const float* t, const float* dsdx, const float* dtdx, + const float* dsdy, const float* dtdy, int nchannels, + float* result, float* dresultds = nullptr, + float* dresultdt = nullptr); /// Perform filtered 3D volumetric texture lookups on a batch of /// positions from the same texture, all at once. The "point-like" @@ -1129,23 +1138,18 @@ class OIIO_API TextureSystem { /// found or could not be opened by any available ImageIO /// plugin. /// - virtual bool texture3d (ustring filename, - TextureOptBatch &options, Tex::RunMask mask, - const float *P, const float *dPdx, - const float *dPdy, const float *dPdz, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr, - float *dresultdr=nullptr) = 0; + bool texture3d(ustring filename, TextureOptBatch& options, + Tex::RunMask mask, const float* P, const float* dPdx, + const float* dPdy, const float* dPdz, int nchannels, + float* result, float* dresultds = nullptr, + float* dresultdt = nullptr, float* dresultdr = nullptr); /// Slightly faster version of texture3d() lookup if the app already /// has a texture handle and per-thread info. - virtual bool texture3d (TextureHandle *texture_handle, - Perthread *thread_info, - TextureOptBatch &options, Tex::RunMask mask, - const float *P, const float *dPdx, - const float *dPdy, const float *dPdz, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr, - float *dresultdr=nullptr) = 0; + bool texture3d(TextureHandle* texture_handle, Perthread* thread_info, + TextureOptBatch& options, Tex::RunMask mask, const float* P, + const float* dPdx, const float* dPdy, const float* dPdz, + int nchannels, float* result, float* dresultds = nullptr, + float* dresultdt = nullptr, float* dresultdr = nullptr); /// Perform filtered directional environment map lookups on a batch of /// directions from the same texture, all at once. The "point-like" @@ -1195,28 +1199,17 @@ class OIIO_API TextureSystem { /// found or could not be opened by any available ImageIO /// plugin. /// - virtual bool environment (ustring filename, - TextureOptBatch &options, Tex::RunMask mask, - const float *R, const float *dRdx, const float *dRdy, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool environment(ustring filename, TextureOptBatch& options, + Tex::RunMask mask, const float* R, const float* dRdx, + const float* dRdy, int nchannels, float* result, + float* dresultds = nullptr, float* dresultdt = nullptr); /// Slightly faster version of environment() if the app already has a /// texture handle and per-thread info. - virtual bool environment (TextureHandle *texture_handle, Perthread *thread_info, - TextureOptBatch &options, Tex::RunMask mask, - const float *R, const float *dRdx, const float *dRdy, - int nchannels, float *result, - float *dresultds=nullptr, float *dresultdt=nullptr) = 0; - - // Batched shadow lookups - virtual bool shadow (ustring filename, - TextureOptBatch &options, Tex::RunMask mask, - const float *P, const float *dPdx, const float *dPdy, - float *result, float *dresultds=nullptr, float *dresultdt=nullptr) = 0; - virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info, - TextureOptBatch &options, Tex::RunMask mask, - const float *P, const float *dPdx, const float *dPdy, - float *result, float *dresultds=nullptr, float *dresultdt=nullptr) = 0; + bool environment(TextureHandle* texture_handle, Perthread* thread_info, + TextureOptBatch& options, Tex::RunMask mask, + const float* R, const float* dRdx, const float* dRdy, + int nchannels, float* result, float* dresultds = nullptr, + float* dresultdt = nullptr); /// @} @@ -1227,7 +1220,7 @@ class OIIO_API TextureSystem { /// Given possibly-relative 'filename' (UTF-8 encoded), resolve it using /// the search path rules and return the full resolved filename. - virtual std::string resolve_filename (const std::string &filename) const=0; + std::string resolve_filename(const std::string& filename) const; /// Get information or metadata about the named texture and store it in /// `*data`. @@ -1412,15 +1405,15 @@ class OIIO_API TextureSystem { /// Except for the `"exists"` query, a file that does not /// exist or could not be read properly as an image also /// constitutes a query failure that will return `false`. - virtual bool get_texture_info (ustring filename, int subimage, - ustring dataname, TypeDesc datatype, void *data) = 0; + bool get_texture_info(ustring filename, int subimage, ustring dataname, + TypeDesc datatype, void* data); /// A more efficient variety of `get_texture_info()` for cases where you /// can use a `TextureHandle*` to specify the image and optionally have /// a `Perthread*` for the calling thread. - virtual bool get_texture_info (TextureHandle *texture_handle, - Perthread *thread_info, int subimage, - ustring dataname, TypeDesc datatype, void *data) = 0; + bool get_texture_info(TextureHandle* texture_handle, Perthread* thread_info, + int subimage, ustring dataname, TypeDesc datatype, + void* data); /// Copy the ImageSpec associated with the named texture (the first /// subimage by default, or as set by `subimage`). @@ -1438,14 +1431,12 @@ class OIIO_API TextureSystem { /// as being unable to find, open, or read the file, or if /// it does not contain the designated subimage or MIP /// level). - virtual bool get_imagespec (ustring filename, int subimage, - ImageSpec &spec) = 0; + bool get_imagespec(ustring filename, int subimage, ImageSpec& spec); /// A more efficient variety of `get_imagespec()` for cases where you /// can use a `TextureHandle*` to specify the image and optionally have /// a `Perthread*` for the calling thread. - virtual bool get_imagespec (TextureHandle *texture_handle, - Perthread *thread_info, int subimage, - ImageSpec &spec) = 0; + bool get_imagespec(TextureHandle* texture_handle, Perthread* thread_info, + int subimage, ImageSpec& spec); /// Return a pointer to an ImageSpec associated with the named texture /// if the file is found and is an image format that can be read, @@ -1468,13 +1459,13 @@ class OIIO_API TextureSystem { /// A pointer to the spec, if the image is found and able to /// be opened and read by an available image format plugin, /// and the designated subimage exists. - virtual const ImageSpec *imagespec (ustring filename, int subimage=0) = 0; + const ImageSpec* imagespec(ustring filename, int subimage = 0); /// A more efficient variety of `imagespec()` for cases where you can /// use a `TextureHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual const ImageSpec *imagespec (TextureHandle *texture_handle, - Perthread *thread_info = nullptr, - int subimage=0) = 0; + const ImageSpec* imagespec(TextureHandle* texture_handle, + Perthread* thread_info = nullptr, + int subimage = 0); /// For a texture specified by name, retrieve the rectangle of raw /// unfiltered texels from the subimage specified in `options` and at @@ -1517,20 +1508,17 @@ class OIIO_API TextureSystem { /// /// @returns /// `true` for success, `false` for failure. - virtual bool get_texels (ustring filename, TextureOpt &options, - int miplevel, int xbegin, int xend, - int ybegin, int yend, int zbegin, int zend, - int chbegin, int chend, - TypeDesc format, void *result) = 0; + bool get_texels(ustring filename, TextureOpt& options, int miplevel, + int xbegin, int xend, int ybegin, int yend, int zbegin, + int zend, int chbegin, int chend, TypeDesc format, + void* result); /// A more efficient variety of `get_texels()` for cases where you can /// use a `TextureHandle*` to specify the image and optionally have a /// `Perthread*` for the calling thread. - virtual bool get_texels (TextureHandle *texture_handle, - Perthread *thread_info, TextureOpt &options, - int miplevel, int xbegin, int xend, - int ybegin, int yend, int zbegin, int zend, - int chbegin, int chend, - TypeDesc format, void *result) = 0; + bool get_texels(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, int miplevel, int xbegin, int xend, + int ybegin, int yend, int zbegin, int zend, int chbegin, + int chend, TypeDesc format, void* result); /// @} @@ -1541,12 +1529,12 @@ class OIIO_API TextureSystem { /// Is the UTF-8 encoded filename a UDIM pattern? /// /// This method was added in OpenImageIO 2.3. - virtual bool is_udim(ustring filename) = 0; + bool is_udim(ustring filename); /// Does the handle refer to a file that's a UDIM pattern? /// /// This method was added in OpenImageIO 2.3. - virtual bool is_udim(TextureHandle* udimfile) = 0; + bool is_udim(TextureHandle* udimfile); /// For a UDIM filename pattern (UTF-8 encoded) and texture coordinates, /// return the TextureHandle pointer for the concrete tile file it refers @@ -1554,17 +1542,15 @@ class OIIO_API TextureSystem { /// allowed to be sparse). /// /// This method was added in OpenImageIO 2.3. - virtual TextureHandle* resolve_udim(ustring udimpattern, - float s, float t) = 0; + TextureHandle* resolve_udim(ustring udimpattern, float s, float t); /// A more efficient variety of `resolve_udim()` for cases where you /// have the `TextureHandle*` that corresponds to the "virtual" UDIM /// file and optionally have a `Perthread*` for the calling thread. /// /// This method was added in OpenImageIO 2.3. - virtual TextureHandle* resolve_udim(TextureHandle* udimfile, - Perthread* thread_info, - float s, float t) = 0; + TextureHandle* resolve_udim(TextureHandle* udimfile, Perthread* thread_info, + float s, float t); /// Produce a full inventory of the set of concrete files comprising the /// UDIM set specified by UTF-8 encoded `udimpattern`. The apparent @@ -1577,19 +1563,17 @@ class OIIO_API TextureSystem { /// `utile + vtile * nvtiles`. /// /// This method was added in OpenImageIO 2.3. - virtual void inventory_udim(ustring udimpattern, - std::vector& filenames, - int& nutiles, int& nvtiles) = 0; + void inventory_udim(ustring udimpattern, std::vector& filenames, + int& nutiles, int& nvtiles); /// A more efficient variety of `inventory_udim()` for cases where you /// have the `TextureHandle*` that corresponds to the "virtual" UDIM /// file and optionally have a `Perthread*` for the calling thread. /// /// This method was added in OpenImageIO 2.3. - virtual void inventory_udim(TextureHandle* udimfile, - Perthread* thread_info, - std::vector& filenames, - int& nutiles, int& nvtiles) = 0; + void inventory_udim(TextureHandle* udimfile, Perthread* thread_info, + std::vector& filenames, int& nutiles, + int& nvtiles); /// @} /// @{ @@ -1600,11 +1584,11 @@ class OIIO_API TextureSystem { /// encoded), including loaded texture tiles from that texture, and close /// any open file handle associated with the file. This calls /// `ImageCache::invalidate(filename,force)` on the underlying ImageCache. - virtual void invalidate (ustring filename, bool force = true) = 0; + void invalidate(ustring filename, bool force = true); /// Invalidate all cached data for all textures. This calls /// `ImageCache::invalidate_all(force)` on the underlying ImageCache. - virtual void invalidate_all (bool force=false) = 0; + void invalidate_all(bool force = false); /// Close any open file handles associated with a UTF-8 encoded filename, /// but do not invalidate any image spec information or pixels associated @@ -1612,10 +1596,10 @@ class OIIO_API TextureSystem { /// handle resources, or to make it safe for other processes to modify /// textures on disk. This calls `ImageCache::close(force)` on the /// underlying ImageCache. - virtual void close (ustring filename) = 0; + void close(ustring filename); /// `close()` all files known to the cache. - virtual void close_all () = 0; + void close_all(); /// @} @@ -1623,13 +1607,13 @@ class OIIO_API TextureSystem { /// @name Errors and statistics /// Is there a pending error message waiting to be retrieved? - virtual bool has_error() const = 0; + bool has_error() const; /// Return the text of all pending error messages issued against this /// TextureSystem, and clear the pending error message unless `clear` is /// false. If no error message is pending, it will return an empty /// string. - virtual std::string geterror(bool clear = true) const = 0; + std::string geterror(bool clear = true) const; /// Returns a big string containing useful statistics about the /// TextureSystem operations, suitable for saving to a file or @@ -1639,34 +1623,36 @@ class OIIO_API TextureSystem { /// the returned string will also contain all the statistics of the /// underlying ImageCache, but if false will only contain /// texture-specific statistics. - virtual std::string getstats (int level=1, bool icstats=true) const = 0; + std::string getstats(int level = 1, bool icstats = true) const; /// Reset most statistics to be as they were with a fresh TextureSystem. /// Caveat emptor: this does not flush the cache itself, so the resulting /// statistics from the next set of texture requests will not match the /// number of tile reads, etc., that would have resulted from a new /// TextureSystem. - virtual void reset_stats () = 0; + void reset_stats(); /// @} /// Return an opaque, non-owning pointer to the underlying ImageCache /// (if there is one). - virtual std::shared_ptr imagecache() const = 0; - - virtual ~TextureSystem () { } + std::shared_ptr imagecache() const; // For testing -- do not use static void unit_test_hash(); -protected: + TextureSystem(std::shared_ptr imagecache); + ~TextureSystem(); + +private: + // PIMPL idiom + using Impl = TextureSystemImpl; + // class Impl; + static void impl_deleter(Impl*); + std::unique_ptr m_impl; + // User code should never directly construct or destruct a TextureSystem. // Always use TextureSystem::create() and TextureSystem::destroy(). - TextureSystem (void) { } -private: - // Make delete private and unimplemented in order to prevent apps - // from calling it. Instead, they should call TextureSystem::destroy(). - void operator delete(void* /*todel*/) {} }; diff --git a/src/libtexture/environment.cpp b/src/libtexture/environment.cpp index 535a89853c..d9ec38bbd9 100644 --- a/src/libtexture/environment.cpp +++ b/src/libtexture/environment.cpp @@ -203,6 +203,54 @@ OIIO_NAMESPACE_BEGIN using namespace pvt; using namespace simd; + +bool +TextureSystem::environment(ustring filename, TextureOpt& options, V3fParam R, + V3fParam dRdx, V3fParam dRdy, int nchannels, + float* result, float* dresultds, float* dresultdt) +{ + return m_impl->environment(filename, options, R, dRdx, dRdy, nchannels, + result, dresultds, dresultdt); +} + + +bool +TextureSystem::environment(TextureHandle* texture_handle, + Perthread* thread_info, TextureOpt& options, + V3fParam R, V3fParam dRdx, V3fParam dRdy, + int nchannels, float* result, float* dresultds, + float* dresultdt) +{ + return m_impl->environment(texture_handle, thread_info, options, R, dRdx, + dRdy, nchannels, result, dresultds, dresultdt); +} + + +bool +TextureSystem::environment(ustring filename, TextureOptBatch& options, + Tex::RunMask mask, const float* R, const float* dRdx, + const float* dRdy, int nchannels, float* result, + float* dresultds, float* dresultdt) +{ + return m_impl->environment(filename, options, mask, R, dRdx, dRdy, + nchannels, result, dresultds, dresultdt); +} + + +bool +TextureSystem::environment(TextureHandle* texture_handle, + Perthread* thread_info, TextureOptBatch& options, + Tex::RunMask mask, const float* R, const float* dRdx, + const float* dRdy, int nchannels, float* result, + float* dresultds, float* dresultdt) +{ + return m_impl->environment(texture_handle, thread_info, options, mask, R, + dRdx, dRdy, nchannels, result, dresultds, + dresultdt); +} + + + namespace pvt { @@ -225,6 +273,8 @@ vector_to_latlong(const Imath::V3f& R, bool y_is_up, float& s, float& t) t = 0.0f; } +} // namespace pvt + bool @@ -594,6 +644,4 @@ TextureSystemImpl::environment(ustring filename, TextureOptBatch& options, } -} // end namespace pvt - OIIO_NAMESPACE_END diff --git a/src/libtexture/imagecache.cpp b/src/libtexture/imagecache.cpp index 9c7c480135..e520aebf90 100644 --- a/src/libtexture/imagecache.cpp +++ b/src/libtexture/imagecache.cpp @@ -39,14 +39,11 @@ OIIO_NAMESPACE_BEGIN using namespace pvt; -namespace pvt { - // The static perthread mutex needs to outlive the shared_image_cache // instance, so must be declared first in this file to avoid static // initialization order problems. spin_mutex ImageCacheImpl::m_perthread_info_mutex; -} // namespace pvt namespace { // anonymous @@ -122,9 +119,6 @@ redundantbytes_compare(const ImageCacheFileRef& a, const ImageCacheFileRef& b) }; // end anonymous namespace -namespace pvt { // namespace pvt - - void ImageCacheStatistics::init() @@ -1242,6 +1236,19 @@ ImageCacheFile::mark_broken(string_view error) +size_t +ImageCacheFile::heapsize() const +{ + size_t size = pvt::heapsize(m_subimages); + size += pvt::heapsize(m_configspec); + size += pvt::heapsize(m_input); + size += pvt::heapsize(m_mipreadcount); + size += pvt::heapsize(m_udim_lookup); + return size; +} + + + ImageCacheFile* ImageCacheImpl::find_file(ustring filename, ImageCachePerThreadInfo* thread_info, @@ -2468,7 +2475,7 @@ ImageCacheImpl::getattribute(string_view name, TypeDesc type, void* val) const if (Strutil::starts_with(name, "stat:")) { // Stats we can just grab - ATTR_DECODE("stat:cache_footprint", long long, footprint(*this)); + ATTR_DECODE("stat:cache_footprint", long long, pvt::footprint(*this)); ATTR_DECODE("stat:cache_memory_used", long long, m_mem_used); ATTR_DECODE("stat:tiles_created", int, m_stat_tiles_created); ATTR_DECODE("stat:tiles_current", int, m_stat_tiles_current); @@ -3930,7 +3937,139 @@ ImageCacheImpl::append_error(string_view message) const -} // end namespace pvt +size_t +ImageCacheImpl::heapsize() const +{ + using OIIO::pvt::footprint; + using OIIO::pvt::heapsize; + + size_t size = 0; + // strings + size += heapsize(m_searchpath) + heapsize(m_plugin_searchpath) + + heapsize(m_searchdirs); + // thread info + size += heapsize(m_all_perthread_info); + // tile cache + for (TileCache::iterator t = m_tilecache.begin(), e = m_tilecache.end(); + t != e; ++t) + size += footprint(t->first) + footprint(t->second); + // files + for (FilenameMap::iterator t = m_files.begin(), e = m_files.end(); t != e; + ++t) + size += footprint(t->first) + footprint(t->second); + // finger prints; we only account for references, this map does not own the files. + constexpr size_t sizeofFingerprintPair = sizeof(ustring) + + sizeof(ImageCacheFileRef); + size += m_fingerprints.size() * sizeofFingerprintPair; + return size; +} + + + +size_t +ImageCacheImpl::footprint(ImageCacheFootprint& output) const +{ + using OIIO::pvt::footprint; + using OIIO::pvt::heapsize; + + // strings + output.ic_str_count = m_searchdirs.size() + 2; + output.ic_str_mem = heapsize(m_searchdirs) + heapsize(m_searchpath) + + heapsize(m_plugin_searchpath); + + // thread info + output.ic_thdi_count = m_all_perthread_info.size(); + output.ic_thdi_mem = heapsize(m_all_perthread_info); + + // tile cache + output.ic_tile_count = m_tilecache.size(); + for (TileCache::iterator t = m_tilecache.begin(), e = m_tilecache.end(); + t != e; ++t) + output.ic_tile_mem += footprint(t->first) + footprint(t->second); + + // finger prints; we only account for references, this map does not own the files. + constexpr size_t sizeofFingerprintPair = sizeof(ustring) + + sizeof(ImageCacheFileRef); + output.ic_fgpt_count = m_fingerprints.size(); + output.ic_fgpt_mem = output.ic_fgpt_count * sizeofFingerprintPair; + + // files; count the footprint of files, subimages, level infos, image inputs, image specs + for (FilenameMap::iterator t = m_files.begin(), e = m_files.end(); t != e; + ++t) { + // get file format ustring; files with empty file format are simply constant valued. + const ImageCacheFile& file(*t->second); + const ustring& format = !file.fileformat().empty() + ? file.fileformat() + : ImageCacheFootprint::uconstant; + + const size_t fileftp = footprint(t->first) + footprint(t->second); + output.add(fileftp, format); + + const size_t specftp = footprint(file.m_configspec); + output.add(specftp, format); + + const size_t inputftp = footprint(file.m_input); + output.add(inputftp, format); + + // subimages + for (int s = 0, send = file.subimages(); s < send; ++s) { + const ImageCacheFile::SubimageInfo& sub(file.subimageinfo(s)); + const size_t subftp = footprint(sub); + output.add(subftp, format); + + // level infos + for (const auto& level : sub.levels) { + const size_t lvlftp = footprint(level); + output.add(lvlftp, format); + + // extra infos; there are two ImageSpec structures stored in each LevelInfos, + // and they turn out to be memory heavy, so we further break that down next. + const size_t lvlspecftp = footprint(level.m_spec) + + footprint(level.nativespec); + const size_t lvlattrftp + = (level.m_spec ? footprint(level.m_spec->extra_attribs) + : 0) + + footprint(level.nativespec.extra_attribs); + const size_t lvlchanftp + = (level.m_spec ? footprint(level.m_spec->channelnames) : 0) + + footprint(level.nativespec.channelnames); + output.add(lvlspecftp, format); + output.add(2 * sizeof(ImageSpec), + format); + output.add(lvlattrftp, format); + output.add(lvlchanftp, format); + } + } + } + + // update total memory + output.ic_mem += output.ic_str_mem; + output.ic_mem += output.ic_tile_mem; + output.ic_mem += output.ic_thdi_mem; + output.ic_mem += output.fmap.find(ImageCacheFootprint::utotal)->second[kMem]; + output.ic_mem += output.ic_fgpt_mem; + + return output.ic_mem; +} + + + +void +ImageCache::impl_deleter(ImageCacheImpl* todel) +{ + delete todel; +} + + + +ImageCache::ImageCache() + : m_impl(new ImageCacheImpl, &impl_deleter) +{ +} + + + +ImageCache::~ImageCache() {} @@ -3942,12 +4081,12 @@ ImageCache::create(bool shared) // exists, just return it, otherwise record the new cache. spin_lock guard(shared_image_cache_mutex); if (!shared_image_cache) - shared_image_cache = std::make_shared(); + shared_image_cache = std::make_shared(); return shared_image_cache; } // Doesn't need a shared cache - return std::make_shared(); + return std::make_shared(); } @@ -3972,4 +4111,347 @@ ImageCache::destroy(std::shared_ptr& cache, bool teardown) } + +bool +ImageCache::attribute(string_view name, TypeDesc type, const void* val) +{ + return m_impl->attribute(name, type, val); +} + + + +bool +ImageCache::getattribute(string_view name, TypeDesc type, void* val) const +{ + return m_impl->getattribute(name, type, val); +} + + +TypeDesc +ImageCache::getattributetype(string_view name) const +{ + return m_impl->getattributetype(name); +} + + + +ImageCache::Perthread* +ImageCache::get_perthread_info(Perthread* thread_info) +{ + return m_impl->get_perthread_info(thread_info); +} + + + +ImageCache::Perthread* +ImageCache::create_thread_info() +{ + return m_impl->create_thread_info(); +} + + + +void +ImageCache::destroy_thread_info(Perthread* thread_info) +{ + m_impl->destroy_thread_info(thread_info); +} + + + +ImageCache::ImageHandle* +ImageCache::get_image_handle(ustring filename, Perthread* thread_info, + const TextureOpt* options) +{ + return m_impl->get_image_handle(filename, thread_info, options); +} + + + +bool +ImageCache::good(ImageHandle* file) +{ + return m_impl->good(file); +} + + + +ustring +ImageCache::filename_from_handle(ImageHandle* handle) +{ + return m_impl->filename_from_handle(handle); +} + + + +std::string +ImageCache::resolve_filename(const std::string& filename) const +{ + return m_impl->resolve_filename(filename); +} + + + +bool +ImageCache::get_image_info(ustring filename, int subimage, int miplevel, + ustring dataname, TypeDesc datatype, void* data) +{ + return m_impl->get_image_info(filename, subimage, miplevel, dataname, + datatype, data); +} + + + +bool +ImageCache::get_image_info(ImageHandle* file, Perthread* thread_info, + int subimage, int miplevel, ustring dataname, + TypeDesc datatype, void* data) +{ + return m_impl->get_image_info(file, thread_info, subimage, miplevel, + dataname, datatype, data); +} + + + +bool +ImageCache::get_imagespec(ustring filename, ImageSpec& spec, int subimage, + int miplevel, bool native) +{ + return m_impl->get_imagespec(filename, spec, subimage, miplevel, native); +} + + +bool +ImageCache::get_imagespec(ImageHandle* file, Perthread* thread_info, + ImageSpec& spec, int subimage, int miplevel, + bool native) +{ + return m_impl->get_imagespec(file, thread_info, spec, subimage, miplevel, + native); +} + + + +const ImageSpec* +ImageCache::imagespec(ustring filename, int subimage, int miplevel, bool native) +{ + return m_impl->imagespec(filename, subimage, miplevel, native); +} + + +const ImageSpec* +ImageCache::imagespec(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, bool native) +{ + return m_impl->imagespec(file, thread_info, subimage, miplevel, native); +} + + + +bool +ImageCache::get_thumbnail(ustring filename, ImageBuf& thumbnail, int subimage) +{ + return m_impl->get_thumbnail(filename, thumbnail, subimage); +} + + +bool +ImageCache::get_thumbnail(ImageHandle* file, Perthread* thread_info, + ImageBuf& thumbnail, int subimage) +{ + return m_impl->get_thumbnail(file, thread_info, thumbnail, subimage); +} + + + +bool +ImageCache::get_pixels(ustring filename, int subimage, int miplevel, int xbegin, + int xend, int ybegin, int yend, int zbegin, int zend, + int chbegin, int chend, TypeDesc format, void* result, + stride_t xstride, stride_t ystride, stride_t zstride, + int cache_chbegin, int cache_chend) +{ + return m_impl->get_pixels(filename, subimage, miplevel, xbegin, xend, + ybegin, yend, zbegin, zend, chbegin, chend, + format, result, xstride, ystride, zstride, + cache_chbegin, cache_chend); +} + + +bool +ImageCache::get_pixels(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, int xbegin, int xend, int ybegin, int yend, + int zbegin, int zend, int chbegin, int chend, + TypeDesc format, void* result, stride_t xstride, + stride_t ystride, stride_t zstride, int cache_chbegin, + int cache_chend) +{ + return m_impl->get_pixels(file, thread_info, subimage, miplevel, xbegin, + xend, ybegin, yend, zbegin, zend, chbegin, chend, + format, result, xstride, ystride, zstride, + cache_chbegin, cache_chend); +} + + + +bool +ImageCache::get_pixels(ustring filename, int subimage, int miplevel, int xbegin, + int xend, int ybegin, int yend, int zbegin, int zend, + TypeDesc format, void* result) +{ + return m_impl->get_pixels(filename, subimage, miplevel, xbegin, xend, + ybegin, yend, zbegin, zend, format, result); +} + + +bool +ImageCache::get_pixels(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, int xbegin, int xend, int ybegin, int yend, + int zbegin, int zend, TypeDesc format, void* result) +{ + return m_impl->get_pixels(file, thread_info, subimage, miplevel, xbegin, + xend, ybegin, yend, zbegin, zend, format, result); +} + + + +void +ImageCache::invalidate(ustring filename, bool force) +{ + m_impl->invalidate(filename, force); +} + + +void +ImageCache::invalidate(ImageHandle* file, bool force) +{ + m_impl->invalidate(file, force); +} + + +void +ImageCache::invalidate_all(bool force) +{ + m_impl->invalidate_all(force); +} + + +void +ImageCache::close(ustring filename) +{ + m_impl->close(filename); +} + + +void +ImageCache::close_all() +{ + m_impl->close_all(); +} + + +ImageCache::Tile* +ImageCache::get_tile(ustring filename, int subimage, int miplevel, int x, int y, + int z, int chbegin, int chend) +{ + return m_impl->get_tile(filename, subimage, miplevel, x, y, z, chbegin, + chend); +} + + +ImageCache::Tile* +ImageCache::get_tile(ImageHandle* file, Perthread* thread_info, int subimage, + int miplevel, int x, int y, int z, int chbegin, int chend) +{ + return m_impl->get_tile(file, thread_info, subimage, miplevel, x, y, z, + chbegin, chend); +} + + + +void +ImageCache::release_tile(Tile* tile) const +{ + m_impl->release_tile(tile); +} + + + +TypeDesc +ImageCache::tile_format(const Tile* tile) const +{ + return m_impl->tile_format(tile); +} + + + +ROI +ImageCache::tile_roi(const Tile* tile) const +{ + return m_impl->tile_roi(tile); +} + + + +const void* +ImageCache::tile_pixels(Tile* tile, TypeDesc& format) const +{ + return m_impl->tile_pixels(tile, format); +} + + + +bool +ImageCache::add_file(ustring filename, ImageInput::Creator creator, + const ImageSpec* config, bool replace) +{ + return m_impl->add_file(filename, creator, config, replace); +} + + + +bool +ImageCache::add_tile(ustring filename, int subimage, int miplevel, int x, int y, + int z, int chbegin, int chend, TypeDesc format, + const void* buffer, stride_t xstride, stride_t ystride, + stride_t zstride, bool copy) +{ + return m_impl->add_tile(filename, subimage, miplevel, x, y, z, chbegin, + chend, format, buffer, xstride, ystride, zstride, + copy); +} + + + +bool +ImageCache::has_error() const +{ + return m_impl->has_error(); +} + + + +std::string +ImageCache::geterror(bool clear) const +{ + return m_impl->geterror(clear); +} + + + +std::string +ImageCache::getstats(int level) const +{ + return m_impl->getstats(level); +} + + + +void +ImageCache::reset_stats() +{ + m_impl->reset_stats(); +} + + OIIO_NAMESPACE_END diff --git a/src/libtexture/imagecache_memory_print.h b/src/libtexture/imagecache_memory_print.h index 1c8cdeff17..369dc52ffe 100644 --- a/src/libtexture/imagecache_memory_print.h +++ b/src/libtexture/imagecache_memory_print.h @@ -16,8 +16,6 @@ OIIO_NAMESPACE_BEGIN -namespace pvt { - //// Memory tracking helper to get ImageCacheImpl statistics //! recorded entries per file format @@ -39,9 +37,12 @@ enum FileFootprintEnty : uint8_t { kFootprintEntrySize }; + typedef std::array FileFootprint; typedef tsl::robin_map FileFootprintMap; + + struct ImageCacheFootprint { static const ustring utotal; static const ustring uconstant; @@ -83,97 +84,22 @@ struct ImageCacheFootprint { const ustring ImageCacheFootprint::utotal = ustring("total"); const ustring ImageCacheFootprint::uconstant = ustring("constant"); + + /// Fills the parameter with a memory breakdown of the ImageCache. inline size_t footprint(const ImageCacheImpl& ic, ImageCacheFootprint& output) { - // strings - output.ic_str_count = ic.m_searchdirs.size() + 2; - output.ic_str_mem = heapsize(ic.m_searchdirs) + heapsize(ic.m_searchpath) - + heapsize(ic.m_plugin_searchpath); - - // thread info - output.ic_thdi_count = ic.m_all_perthread_info.size(); - output.ic_thdi_mem = heapsize(ic.m_all_perthread_info); - - // tile cache - output.ic_tile_count = ic.m_tilecache.size(); - for (TileCache::iterator t = ic.m_tilecache.begin(), - e = ic.m_tilecache.end(); - t != e; ++t) - output.ic_tile_mem += footprint(t->first) + footprint(t->second); - - // finger prints; we only account for references, this map does not own the files. - constexpr size_t sizeofFingerprintPair = sizeof(ustring) - + sizeof(ImageCacheFileRef); - output.ic_fgpt_count = ic.m_fingerprints.size(); - output.ic_fgpt_mem = output.ic_fgpt_count * sizeofFingerprintPair; - - // files; count the footprint of files, subimages, level infos, image inputs, image specs - for (FilenameMap::iterator t = ic.m_files.begin(), e = ic.m_files.end(); - t != e; ++t) { - // get file format ustring; files with empty file format are simply constant valued. - const ImageCacheFile& file(*t->second); - const ustring& format = !file.fileformat().empty() - ? file.fileformat() - : ImageCacheFootprint::uconstant; - - const size_t fileftp = footprint(t->first) + footprint(t->second); - output.add(fileftp, format); - - const size_t specftp = footprint(file.m_configspec); - output.add(specftp, format); - - const size_t inputftp = footprint(file.m_input); - output.add(inputftp, format); - - // subimages - for (int s = 0, send = file.subimages(); s < send; ++s) { - const ImageCacheFile::SubimageInfo& sub(file.subimageinfo(s)); - const size_t subftp = footprint(sub); - output.add(subftp, format); - - // level infos - for (const auto& level : sub.levels) { - const size_t lvlftp = footprint(level); - output.add(lvlftp, format); - - // extra infos; there are two ImageSpec structures stored in each LevelInfos, - // and they turn out to be memory heavy, so we further break that down next. - const size_t lvlspecftp = footprint(level.m_spec) - + footprint(level.nativespec); - const size_t lvlattrftp - = (level.m_spec ? footprint(level.m_spec->extra_attribs) - : 0) - + footprint(level.nativespec.extra_attribs); - const size_t lvlchanftp - = (level.m_spec ? footprint(level.m_spec->channelnames) : 0) - + footprint(level.nativespec.channelnames); - output.add(lvlspecftp, format); - output.add(2 * sizeof(ImageSpec), - format); - output.add(lvlattrftp, format); - output.add(lvlchanftp, format); - } - } - } - - // update total memory - output.ic_mem += output.ic_str_mem; - output.ic_mem += output.ic_tile_mem; - output.ic_mem += output.ic_thdi_mem; - output.ic_mem += output.fmap.find(ImageCacheFootprint::utotal)->second[kMem]; - output.ic_mem += output.ic_fgpt_mem; - - return output.ic_mem; + return ic.footprint(output); } + inline void printImageCacheMemory(std::ostream& out, const ImageCacheImpl& ic) { // get memory data - pvt::ImageCacheFootprint data; - pvt::footprint(ic, data); + ImageCacheFootprint data; + footprint(ic, data); // print image cache memory usage print(out, " Cache : {}\n", Strutil::memformat(data.ic_mem)); @@ -190,8 +116,8 @@ printImageCacheMemory(std::ostream& out, const ImageCacheImpl& ic) data.fmap[ImageCacheFootprint::utotal][kCount]); // print file formats memory usage - for (pvt::FileFootprintMap::const_iterator t = data.fmap.begin(), - e = data.fmap.end(); + for (FileFootprintMap::const_iterator t = data.fmap.begin(), + e = data.fmap.end(); t != e; ++t) { if (t.key() == ImageCacheFootprint::utotal) continue; @@ -229,6 +155,4 @@ printImageCacheMemory(std::ostream& out, const ImageCacheImpl& ic) } } -} // namespace pvt - -OIIO_NAMESPACE_END \ No newline at end of file +OIIO_NAMESPACE_END diff --git a/src/libtexture/imagecache_memory_pvt.h b/src/libtexture/imagecache_memory_pvt.h index 10ee4ee8b9..debd22b8be 100644 --- a/src/libtexture/imagecache_memory_pvt.h +++ b/src/libtexture/imagecache_memory_pvt.h @@ -51,12 +51,7 @@ template<> inline size_t heapsize(const ImageCacheFile& file) { - size_t size = heapsize(file.m_subimages); - size += heapsize(file.m_configspec); - size += heapsize(file.m_input); - size += heapsize(file.m_mipreadcount); - size += heapsize(file.m_udim_lookup); - return size; + return file.heapsize(); } // heapsize specialization for ImageCacheTile @@ -72,9 +67,7 @@ template<> inline size_t heapsize(const ImageCachePerThreadInfo& info) { - /// TODO: this should take into account the two last tiles, if their refcount is zero. - constexpr size_t sizeofPair = sizeof(ustring) + sizeof(ImageCacheFile*); - return info.m_thread_files.size() * sizeofPair; + return info.heapsize(); } // heapsize specialization for ImageCacheImpl @@ -82,28 +75,9 @@ template<> inline size_t heapsize(const ImageCacheImpl& ic) { - size_t size = 0; - // strings - size += heapsize(ic.m_searchpath) + heapsize(ic.m_plugin_searchpath) - + heapsize(ic.m_searchdirs); - // thread info - size += heapsize(ic.m_all_perthread_info); - // tile cache - for (TileCache::iterator t = ic.m_tilecache.begin(), - e = ic.m_tilecache.end(); - t != e; ++t) - size += footprint(t->first) + footprint(t->second); - // files - for (FilenameMap::iterator t = ic.m_files.begin(), e = ic.m_files.end(); - t != e; ++t) - size += footprint(t->first) + footprint(t->second); - // finger prints; we only account for references, this map does not own the files. - constexpr size_t sizeofFingerprintPair = sizeof(ustring) - + sizeof(ImageCacheFileRef); - size += ic.m_fingerprints.size() * sizeofFingerprintPair; - return size; + return ic.heapsize(); } } // namespace pvt -OIIO_NAMESPACE_END \ No newline at end of file +OIIO_NAMESPACE_END diff --git a/src/libtexture/imagecache_pvt.h b/src/libtexture/imagecache_pvt.h index 262ee99ca1..f8f8b33284 100644 --- a/src/libtexture/imagecache_pvt.h +++ b/src/libtexture/imagecache_pvt.h @@ -4,7 +4,7 @@ /// \file -/// Non-public classes used internally by ImgeCacheImpl. +/// Non-public classes used internally by ImageCacheImpl. #ifndef OPENIMAGEIO_IMAGECACHE_PVT_H @@ -25,7 +25,6 @@ OIIO_NAMESPACE_BEGIN -namespace pvt { #ifndef NDEBUG # define IMAGECACHE_TIME_STATS 1 @@ -40,16 +39,21 @@ namespace pvt { #define FILE_CACHE_SHARDS 64 #define TILE_CACHE_SHARDS 128 + + struct TileID; class ImageCacheImpl; -class ImageCachePerThreadInfo; struct ImageCacheFootprint; +namespace pvt { + const char* texture_format_name(TexFormat f); const char* texture_type_name(TexFormat f); +} // namespace pvt + /// Structure to hold IC and TS statistics. We combine into a single @@ -107,6 +111,9 @@ struct ImageCacheStatistics { +namespace pvt { + + struct UdimInfo { ustring filename; std::atomic icfile { nullptr }; @@ -137,6 +144,8 @@ struct UdimInfo { } }; +} // namespace pvt + /// Unique in-memory record for each image file on disk. Note that @@ -150,6 +159,10 @@ struct UdimInfo { /// thread-specific IC data including microcache and statistics. /// class OIIO_API ImageCacheFile final : public RefCnt { + using TexFormat = pvt::TexFormat; + using EnvLayout = pvt::EnvLayout; + using UdimInfo = pvt::UdimInfo; + public: ImageCacheFile(ImageCacheImpl& imagecache, ImageCachePerThreadInfo* thread_info, ustring filename, @@ -367,6 +380,8 @@ class OIIO_API ImageCacheFile final : public RefCnt { // Return the regex wildcard matching pattern for a udim spec. static std::string udim_to_wildcard(string_view udimpattern); + size_t heapsize() const; + private: ustring m_filename_original; ///< original filename before search path ustring m_filename; ///< Filename @@ -468,12 +483,6 @@ class OIIO_API ImageCacheFile final : public RefCnt { friend class ImageCacheImpl; friend class TextureSystemImpl; friend struct SubimageInfo; - - /// Memory tracking. Specializes the base memory tracking functions from memory.h. - /// declare a friend heapsize definition - template friend inline size_t heapsize(const T&); - /// declare a friend image cache footprint definition - friend inline size_t footprint(const ImageCacheImpl&, ImageCacheFootprint&); }; @@ -732,10 +741,8 @@ class ImageCacheTile final : public RefCnt { int m_tile_width { 0 }; ///< Tile width bool m_valid { false }; ///< Valid pixels bool m_nofree { false }; ///< We do NOT own the pixels, do not free! - volatile bool m_pixels_ready { - false - }; ///< The pixels have been read from disk - atomic_int m_used { 1 }; ///< Used recently + volatile bool m_pixels_ready { false }; // Pixels have been read from disk + atomic_int m_used { 1 }; ///< Used recently }; @@ -754,6 +761,7 @@ typedef unordered_map_concurrent< TileCache; + /// A very small amount of per-thread data that saves us from locking /// the mutex quite as often. We store things here used by both /// ImageCache and TextureSystem, so they don't each need a costly @@ -796,6 +804,13 @@ class ImageCachePerThreadInfo { auto f = m_thread_files.find(n); return f == m_thread_files.end() ? nullptr : f->second; } + + size_t heapsize() const + { + /// TODO: this should take into account the two last tiles, if their refcount is zero. + constexpr size_t sizeofPair = sizeof(ustring) + sizeof(ImageCacheFile*); + return m_thread_files.size() * sizeofPair; + } }; @@ -805,60 +820,65 @@ class ImageCachePerThreadInfo { /// Some of the methods require a pointer to the thread-specific IC data /// including microcache and statistics. /// -class ImageCacheImpl final : public ImageCache { +class ImageCacheImpl { public: + using Perthread = ImageCachePerThreadInfo; + using ImageHandle = ImageCacheFile; + using Tile = ImageCacheTile; + friend class TextureSystem; + friend class TextureSystemImpl; + ImageCacheImpl(); - ~ImageCacheImpl() override; + ~ImageCacheImpl(); - bool attribute(string_view name, TypeDesc type, const void* val) override; - bool attribute(string_view name, int val) override + bool attribute(string_view name, TypeDesc type, const void* val); + bool attribute(string_view name, int val) { - return attribute(name, TypeDesc::INT, &val); + return attribute(name, TypeInt, &val); } - bool attribute(string_view name, float val) override + bool attribute(string_view name, float val) { - return attribute(name, TypeDesc::FLOAT, &val); + return attribute(name, TypeFloat, &val); } - bool attribute(string_view name, double val) override + bool attribute(string_view name, double val) { float f = (float)val; - return attribute(name, TypeDesc::FLOAT, &f); + return attribute(name, TypeFloat, &f); } - bool attribute(string_view name, string_view val) override + bool attribute(string_view name, string_view val) { std::string valstr(val); const char* s = valstr.c_str(); - return attribute(name, TypeDesc::STRING, &s); + return attribute(name, TypeString, &s); } - TypeDesc getattributetype(string_view name) const override; + TypeDesc getattributetype(string_view name) const; - bool getattribute(string_view name, TypeDesc type, - void* val) const override; - bool getattribute(string_view name, int& val) const override + bool getattribute(string_view name, TypeDesc type, void* val) const; + bool getattribute(string_view name, int& val) const { - return getattribute(name, TypeDesc::INT, &val); + return getattribute(name, TypeInt, &val); } - bool getattribute(string_view name, float& val) const override + bool getattribute(string_view name, float& val) const { - return getattribute(name, TypeDesc::FLOAT, &val); + return getattribute(name, TypeFloat, &val); } - bool getattribute(string_view name, double& val) const override + bool getattribute(string_view name, double& val) const { float f; - bool ok = getattribute(name, TypeDesc::FLOAT, &f); + bool ok = getattribute(name, TypeFloat, &f); if (ok) val = f; return ok; } - bool getattribute(string_view name, char** val) const override + bool getattribute(string_view name, char** val) const { - return getattribute(name, TypeDesc::STRING, val); + return getattribute(name, TypeString, val); } - bool getattribute(string_view name, std::string& val) const override + bool getattribute(string_view name, std::string& val) const { ustring s; - bool ok = getattribute(name, TypeDesc::STRING, &s); + bool ok = getattribute(name, TypeString, &s); if (ok) val = s.string(); return ok; @@ -882,7 +902,7 @@ class ImageCacheImpl final : public ImageCache { void get_commontoworld(Imath::M44f& result) const { result = m_Mc2w; } int max_errors_per_file() const { return m_max_errors_per_file; } - std::string resolve_filename(const std::string& filename) const override; + std::string resolve_filename(const std::string& filename) const; // Set m_max_open_files, with logic to try to clamp reasonably. void set_max_open_files(int m); @@ -890,12 +910,11 @@ class ImageCacheImpl final : public ImageCache { /// Get information about the given image. /// bool get_image_info(ustring filename, int subimage, int miplevel, - ustring dataname, TypeDesc datatype, - void* data) override; + ustring dataname, TypeDesc datatype, void* data); bool get_image_info(ImageCacheFile* file, ImageCachePerThreadInfo* thread_info, int subimage, int miplevel, ustring dataname, TypeDesc datatype, - void* data) override; + void* data); /// Get the ImageSpec associated with the named image. If the file /// is found and is an image format that can be read, store a copy @@ -903,18 +922,17 @@ class ImageCacheImpl final : public ImageCache { /// the file was not found or could not be opened as an image file /// by any available ImageIO plugin. bool get_imagespec(ustring filename, ImageSpec& spec, int subimage = 0, - int miplevel = 0, bool native = false) override; + int miplevel = 0, bool native = false); bool get_imagespec(ImageCacheFile* file, ImageCachePerThreadInfo* thread_info, ImageSpec& spec, - int subimage = 0, int miplevel = 0, - bool native = false) override; + int subimage = 0, int miplevel = 0, bool native = false); const ImageSpec* imagespec(ustring filename, int subimage = 0, - int miplevel = 0, bool native = false) override; + int miplevel = 0, bool native = false); const ImageSpec* imagespec(ImageCacheFile* file, ImageCachePerThreadInfo* thread_info = NULL, int subimage = 0, int miplevel = 0, - bool native = false) override; + bool native = false); ImageCacheFile* resolve_udim(ImageCacheFile* udimfile, Perthread* thread_info, int utile, int vtile); @@ -922,26 +940,25 @@ class ImageCacheImpl final : public ImageCache { std::vector& filenames, int& nutiles, int& nvtiles); - bool get_thumbnail(ustring filename, ImageBuf& thumbnail, - int subimage = 0) override; + bool get_thumbnail(ustring filename, ImageBuf& thumbnail, int subimage = 0); bool get_thumbnail(ImageHandle* file, Perthread* thread_info, - ImageBuf& thumbnail, int subimage = 0) override; + ImageBuf& thumbnail, int subimage = 0); // Retrieve a rectangle of raw unfiltered pixels. bool get_pixels(ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, - TypeDesc format, void* result) override; + TypeDesc format, void* result); bool get_pixels(ImageCacheFile* file, ImageCachePerThreadInfo* thread_info, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, - void* result) override; + void* result); bool get_pixels(ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void* result, stride_t xstride = AutoStride, stride_t ystride = AutoStride, stride_t zstride = AutoStride, int cache_chbegin = 0, - int cache_chend = -1) override; + int cache_chend = -1); bool get_pixels(ImageCacheFile* file, ImageCachePerThreadInfo* thread_info, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, @@ -949,7 +966,7 @@ class ImageCacheImpl final : public ImageCache { stride_t xstride = AutoStride, stride_t ystride = AutoStride, stride_t zstride = AutoStride, int cache_chbegin = 0, - int cache_chend = -1) override; + int cache_chend = -1); // Find the ImageCacheFile record for the named image, adding an entry // if it is not already in the cache. This returns a plain old pointer, @@ -976,7 +993,7 @@ class ImageCacheImpl final : public ImageCache { ImageCacheFile* get_image_handle(ustring filename, ImageCachePerThreadInfo* thread_info, - const TextureOpt* options) override + const TextureOpt* options) { if (!thread_info) thread_info = get_perthread_info(); @@ -984,12 +1001,9 @@ class ImageCacheImpl final : public ImageCache { return verify_file(file, thread_info); } - bool good(ImageCacheFile* handle) override - { - return handle && !handle->broken(); - } + bool good(ImageCacheFile* handle) { return handle && !handle->broken(); } - ustring filename_from_handle(ImageCacheFile* handle) override + ustring filename_from_handle(ImageCacheFile* handle) { return handle ? handle->filename() : ustring(); } @@ -1040,41 +1054,40 @@ class ImageCacheImpl final : public ImageCache { } Tile* get_tile(ustring filename, int subimage, int miplevel, int x, int y, - int z, int chbegin, int chend) override; + int z, int chbegin, int chend); Tile* get_tile(ImageHandle* file, Perthread* thread_info, int subimage, - int miplevel, int x, int y, int z, int chbegin, - int chend) override; - void release_tile(Tile* tile) const override; - TypeDesc tile_format(const Tile* tile) const override; - ROI tile_roi(const Tile* tile) const override; - const void* tile_pixels(Tile* tile, TypeDesc& format) const override; + int miplevel, int x, int y, int z, int chbegin, int chend); + void release_tile(Tile* tile) const; + TypeDesc tile_format(const Tile* tile) const; + ROI tile_roi(const Tile* tile) const; + const void* tile_pixels(Tile* tile, TypeDesc& format) const; bool add_file(ustring filename, ImageInput::Creator creator, - const ImageSpec* config, bool replace) override; + const ImageSpec* config, bool replace); bool add_tile(ustring filename, int subimage, int miplevel, int x, int y, int z, int chbegin, int chend, TypeDesc format, const void* buffer, stride_t xstride, stride_t ystride, - stride_t zstride, bool copy) override; + stride_t zstride, bool copy); /// Return the numerical subimage index for the given subimage name, /// as stored in the "oiio:subimagename" metadata. Return -1 if no /// subimage matches its name. int subimage_from_name(ImageCacheFile* file, ustring subimagename); - bool has_error() const override; - std::string geterror(bool clear = true) const override; - std::string getstats(int level = 1) const override; - void reset_stats() override; - void invalidate(ustring filename, bool force) override; - void invalidate(ImageHandle* file, bool force) override; - void invalidate_all(bool force = false) override; - void close(ustring filename) override; - void close_all() override; + bool has_error() const; + std::string geterror(bool clear = true) const; + std::string getstats(int level = 1) const; + void reset_stats(); + void invalidate(ustring filename, bool force); + void invalidate(ImageHandle* file, bool force); + void invalidate_all(bool force = false); + void close(ustring filename); + void close_all(); /// Merge all the per-thread statistics into one set of stats. /// void mergestats(ImageCacheStatistics& merged) const; - void operator delete(void* todel) { ::delete ((char*)todel); } + // void operator delete(void* todel) { ::delete ((char*)todel); } /// Called when a new file is opened, so that the system can track /// the number of simultaneously-opened files. @@ -1121,9 +1134,9 @@ class ImageCacheImpl final : public ImageCache { /// Append a string to the current error message void append_error(string_view message) const; - Perthread* get_perthread_info(Perthread* thread_info = NULL) override; - Perthread* create_thread_info() override; - void destroy_thread_info(Perthread* thread_info) override; + Perthread* get_perthread_info(Perthread* thread_info = NULL); + Perthread* create_thread_info(); + void destroy_thread_info(Perthread* thread_info); /// Ensure that the max_memory_bytes is at least newsize bytes. /// Override the previous value if necessary, with thread-safety. @@ -1136,6 +1149,9 @@ class ImageCacheImpl final : public ImageCache { ustring colorspace() const noexcept { return m_colorspace; } + size_t heapsize() const; + size_t footprint(ImageCacheFootprint& output) const; + private: void init(); @@ -1246,17 +1262,9 @@ class ImageCacheImpl final : public ImageCache { // done it with nobody else interfering. } while (llstat->compare_exchange_strong(*llnewval, *lloldval)); } - - /// declare a friend heapsize definition - template friend inline size_t heapsize(const T&); - /// declare a friend image cache footprint definition - friend inline size_t footprint(const ImageCacheImpl&, ImageCacheFootprint&); }; - -} // end namespace pvt - OIIO_NAMESPACE_END diff --git a/src/libtexture/texture3d.cpp b/src/libtexture/texture3d.cpp index f55c37d389..51fd2d6c1b 100644 --- a/src/libtexture/texture3d.cpp +++ b/src/libtexture/texture3d.cpp @@ -47,7 +47,54 @@ float2float(float val) } // end anonymous namespace -namespace pvt { // namespace pvt +bool +TextureSystem::texture3d(ustring filename, TextureOpt& options, V3fParam P, + V3fParam dPdx, V3fParam dPdy, V3fParam dPdz, + int nchannels, float* result, float* dresultds, + float* dresultdt, float* dresultdr) +{ + return m_impl->texture3d(filename, options, P, dPdx, dPdy, dPdz, nchannels, + result, dresultds, dresultdt, dresultdr); +} + + +bool +TextureSystem::texture3d(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, V3fParam P, V3fParam dPdx, + V3fParam dPdy, V3fParam dPdz, int nchannels, + float* result, float* dresultds, float* dresultdt, + float* dresultdr) +{ + return m_impl->texture3d(texture_handle, thread_info, options, P, dPdx, + dPdy, dPdz, nchannels, result, dresultds, + dresultdt, dresultdr); +} + + +bool +TextureSystem::texture3d(ustring filename, TextureOptBatch& options, + Tex::RunMask mask, const float* P, const float* dPdx, + const float* dPdy, const float* dPdz, int nchannels, + float* result, float* dresultds, float* dresultdt, + float* dresultdr) +{ + return m_impl->texture3d(filename, options, mask, P, dPdx, dPdy, dPdz, + nchannels, result, dresultds, dresultdt, + dresultdr); +} + + +bool +TextureSystem::texture3d(TextureHandle* texture_handle, Perthread* thread_info, + TextureOptBatch& options, Tex::RunMask mask, + const float* P, const float* dPdx, const float* dPdy, + const float* dPdz, int nchannels, float* result, + float* dresultds, float* dresultdt, float* dresultdr) +{ + return m_impl->texture3d(texture_handle, thread_info, options, mask, P, + dPdx, dPdy, dPdz, nchannels, result, dresultds, + dresultdt, dresultdr); +} @@ -714,6 +761,4 @@ TextureSystemImpl::texture3d(ustring filename, TextureOptBatch& options, } -} // end namespace pvt - OIIO_NAMESPACE_END diff --git a/src/libtexture/texture_pvt.h b/src/libtexture/texture_pvt.h index b7d231c35c..66c47dc0bf 100644 --- a/src/libtexture/texture_pvt.h +++ b/src/libtexture/texture_pvt.h @@ -16,107 +16,103 @@ OIIO_NAMESPACE_BEGIN class ImageCache; -class Filter1D; - -namespace pvt { - class TextureSystemImpl; +class Filter1D; #ifndef OPENIMAGEIO_IMAGECACHE_PVT_H -class ImageCacheImpl; class ImageCacheFile; class ImageCacheTile; class ImageCacheTileRef; +class ImageCacheTileID; +class ImageCacheImpl; #endif /// Working implementation of the abstract TextureSystem class. -/// -class TextureSystemImpl final : public TextureSystem { +class TextureSystemImpl { public: - typedef ImageCacheFile TextureFile; + using TextureHandle = TextureSystem::TextureHandle; + using Perthread = TextureSystem::Perthread; + using TextureFile = ImageCacheFile; - TextureSystemImpl(std::shared_ptr imagecache); - ~TextureSystemImpl() override; + TextureSystemImpl(std::shared_ptr imagecache = {}); + ~TextureSystemImpl(); - bool attribute(string_view name, TypeDesc type, const void* val) override; - bool attribute(string_view name, int val) override + bool attribute(string_view name, TypeDesc type, const void* val); + bool attribute(string_view name, int val) { - return attribute(name, TypeDesc::INT, &val); + return attribute(name, TypeInt, &val); } - bool attribute(string_view name, float val) override + bool attribute(string_view name, float val) { - return attribute(name, TypeDesc::FLOAT, &val); + return attribute(name, TypeFloat, &val); } - bool attribute(string_view name, double val) override + bool attribute(string_view name, double val) { float f = (float)val; - return attribute(name, TypeDesc::FLOAT, &f); + return attribute(name, TypeFloat, &f); } - bool attribute(string_view name, string_view val) override + bool attribute(string_view name, string_view val) { std::string valstr(val); const char* s = valstr.c_str(); - return attribute(name, TypeDesc::STRING, &s); + return attribute(name, TypeString, &s); } - TypeDesc getattributetype(string_view name) const override; + TypeDesc getattributetype(string_view name) const; - bool getattribute(string_view name, TypeDesc type, - void* val) const override; - bool getattribute(string_view name, int& val) const override + bool getattribute(string_view name, TypeDesc type, void* val) const; + bool getattribute(string_view name, int& val) const { - return getattribute(name, TypeDesc::INT, &val); + return getattribute(name, TypeInt, &val); } - bool getattribute(string_view name, float& val) const override + bool getattribute(string_view name, float& val) const { - return getattribute(name, TypeDesc::FLOAT, &val); + return getattribute(name, TypeFloat, &val); } - bool getattribute(string_view name, double& val) const override + bool getattribute(string_view name, double& val) const { float f; - bool ok = getattribute(name, TypeDesc::FLOAT, &f); + bool ok = getattribute(name, TypeFloat, &f); if (ok) val = f; return ok; } - bool getattribute(string_view name, char** val) const override + bool getattribute(string_view name, char** val) const { - return getattribute(name, TypeDesc::STRING, val); + return getattribute(name, TypeString, val); } - bool getattribute(string_view name, std::string& val) const override + bool getattribute(string_view name, std::string& val) const { const char* s; - bool ok = getattribute(name, TypeDesc::STRING, &s); + bool ok = getattribute(name, TypeString, &s); if (ok) val = s; return ok; } - // Retrieve options void get_commontoworld(Imath::M44f& result) const { result = m_Mc2w; } - Perthread* get_perthread_info(Perthread* thread_info = NULL) override + Perthread* get_perthread_info(Perthread* thread_info = NULL) { return (Perthread*)m_imagecache->get_perthread_info( (ImageCachePerThreadInfo*)thread_info); } - Perthread* create_thread_info() override + Perthread* create_thread_info() { OIIO_ASSERT(m_imagecache); return (Perthread*)m_imagecache->create_thread_info(); } - void destroy_thread_info(Perthread* threadinfo) override + void destroy_thread_info(Perthread* threadinfo) { OIIO_ASSERT(m_imagecache); m_imagecache->destroy_thread_info((ImageCachePerThreadInfo*)threadinfo); } - TextureHandle* - get_texture_handle(ustring filename, Perthread* thread, - const TextureOpt* options = nullptr) override + TextureHandle* get_texture_handle(ustring filename, Perthread* thread, + const TextureOpt* options = nullptr) { PerThreadInfo* thread_info = thread ? ((PerThreadInfo*)thread) @@ -124,173 +120,134 @@ class TextureSystemImpl final : public TextureSystem { return (TextureHandle*)find_texturefile(filename, thread_info, options); } - bool good(TextureHandle* texture_handle) override + bool good(TextureHandle* texture_handle) { return texture_handle && !((TextureFile*)texture_handle)->broken(); } - ustring filename_from_handle(TextureHandle* handle) override + ustring filename_from_handle(TextureHandle* handle) { return handle ? ((ImageCache::ImageHandle*)handle)->filename() : ustring(); } - int get_colortransform_id(ustring fromspace, - ustring tospace) const override; - int get_colortransform_id(ustringhash fromspace, - ustringhash tospace) const override; + int get_colortransform_id(ustring fromspace, ustring tospace) const; + int get_colortransform_id(ustringhash fromspace, ustringhash tospace) const; bool texture(ustring filename, TextureOpt& options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, int nchannels, float* result, float* dresultds = NULL, - float* dresultdt = NULL) override; + float* dresultdt = NULL); bool texture(TextureHandle* texture_handle, Perthread* thread_info, TextureOpt& options, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, int nchannels, float* result, - float* dresultds = NULL, float* dresultdt = NULL) override; + float* dresultds = NULL, float* dresultdt = NULL); bool texture(ustring filename, TextureOptBatch& options, Tex::RunMask mask, const float* s, const float* t, const float* dsdx, const float* dtdx, const float* dsdy, const float* dtdy, int nchannels, float* result, float* dresultds = nullptr, - float* dresultdt = nullptr) override; + float* dresultdt = nullptr); bool texture(TextureHandle* texture_handle, Perthread* thread_info, TextureOptBatch& options, Tex::RunMask mask, const float* s, const float* t, const float* dsdx, const float* dtdx, const float* dsdy, const float* dtdy, int nchannels, float* result, float* dresultds = nullptr, - float* dresultdt = nullptr) override; + float* dresultdt = nullptr); bool texture3d(ustring filename, TextureOpt& options, V3fParam P, V3fParam dPdx, V3fParam dPdy, V3fParam dPdz, int nchannels, float* result, float* dresultds = NULL, - float* dresultdt = NULL, float* dresultdr = NULL) override; + float* dresultdt = NULL, float* dresultdr = NULL); bool texture3d(TextureHandle* texture_handle, Perthread* thread_info, TextureOpt& options, V3fParam P, V3fParam dPdx, V3fParam dPdy, V3fParam dPdz, int nchannels, float* result, float* dresultds = NULL, float* dresultdt = NULL, - float* dresultdr = NULL) override; + float* dresultdr = NULL); bool texture3d(ustring filename, TextureOptBatch& options, Tex::RunMask mask, const float* P, const float* dPdx, const float* dPdy, const float* dPdz, int nchannels, float* result, float* dresultds = nullptr, - float* dresultdt = nullptr, - float* dresultdr = nullptr) override; + float* dresultdt = nullptr, float* dresultdr = nullptr); bool texture3d(TextureHandle* texture_handle, Perthread* thread_info, TextureOptBatch& options, Tex::RunMask mask, const float* P, const float* dPdx, const float* dPdy, const float* dPdz, int nchannels, float* result, float* dresultds = nullptr, - float* dresultdt = nullptr, - float* dresultdr = nullptr) override; - - bool shadow(ustring /*filename*/, TextureOpt& /*options*/, V3fParam /*P*/, - V3fParam /*dPdx*/, V3fParam /*dPdy*/, float* /*result*/, - float* /*dresultds*/, float* /*dresultdt*/) override - { - return false; - } - bool shadow(TextureHandle* /*texture_handle*/, Perthread* /*thread_info*/, - TextureOpt& /*options*/, V3fParam /*P*/, V3fParam /*dPdx*/, - V3fParam /*dPdy*/, float* /*result*/, float* /*dresultds*/, - float* /*dresultdt*/) override - { - return false; - } - bool shadow(ustring /*filename*/, TextureOptBatch& /*options*/, - Tex::RunMask /*mask*/, const float* /*P*/, - const float* /*dPdx*/, const float* /*dPdy*/, float* /*result*/, - float* /*dresultds*/, float* /*dresultdt*/) override - { - return false; - } - bool shadow(TextureHandle* /*texture_handle*/, Perthread* /*thread_info*/, - TextureOptBatch& /*options*/, Tex::RunMask /*mask*/, - const float* /*P*/, const float* /*dPdx*/, - const float* /*dPdy*/, float* /*result*/, float* /*dresultds*/, - float* /*dresultdt*/) override - { - return false; - } + float* dresultdt = nullptr, float* dresultdr = nullptr); bool environment(ustring filename, TextureOpt& options, V3fParam R, V3fParam dRdx, V3fParam dRdy, int nchannels, float* result, - float* dresultds = NULL, float* dresultdt = NULL) override; + float* dresultds = NULL, float* dresultdt = NULL); bool environment(TextureHandle* texture_handle, Perthread* thread_info, TextureOpt& options, V3fParam R, V3fParam dRdx, V3fParam dRdy, int nchannels, float* result, - float* dresultds = NULL, float* dresultdt = NULL) override; + float* dresultds = NULL, float* dresultdt = NULL); bool environment(ustring filename, TextureOptBatch& options, Tex::RunMask mask, const float* R, const float* dRdx, const float* dRdy, int nchannels, float* result, - float* dresultds = nullptr, - float* dresultdt = nullptr) override; + float* dresultds = nullptr, float* dresultdt = nullptr); bool environment(TextureHandle* texture_handle, Perthread* thread_info, TextureOptBatch& options, Tex::RunMask mask, const float* R, const float* dRdx, const float* dRdy, int nchannels, float* result, float* dresultds = nullptr, - float* dresultdt = nullptr) override; + float* dresultdt = nullptr); - std::string resolve_filename(const std::string& filename) const override; + std::string resolve_filename(const std::string& filename) const; bool get_texture_info(ustring filename, int subimage, ustring dataname, - TypeDesc datatype, void* data) override; + TypeDesc datatype, void* data); bool get_texture_info(TextureHandle* texture_handle, Perthread* thread_info, int subimage, ustring dataname, TypeDesc datatype, - void* data) override; + void* data); - bool get_imagespec(ustring filename, int subimage, - ImageSpec& spec) override; + bool get_imagespec(ustring filename, int subimage, ImageSpec& spec); bool get_imagespec(TextureHandle* texture_handle, Perthread* thread_info, - int subimage, ImageSpec& spec) override; + int subimage, ImageSpec& spec); - const ImageSpec* imagespec(ustring filename, int subimage = 0) override; + const ImageSpec* imagespec(ustring filename, int subimage = 0); const ImageSpec* imagespec(TextureHandle* texture_handle, - Perthread* thread_info = NULL, - int subimage = 0) override; + Perthread* thread_info = NULL, int subimage = 0); bool get_texels(ustring filename, TextureOpt& options, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, - void* result) override; + void* result); bool get_texels(TextureHandle* texture_handle, Perthread* thread_info, TextureOpt& options, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, - int chend, TypeDesc format, void* result) override; + int chend, TypeDesc format, void* result); - bool is_udim(ustring filename) override; - bool is_udim(TextureHandle* udimfile) override; - TextureHandle* resolve_udim(ustring filename, float s, float t) override; + bool is_udim(ustring filename); + bool is_udim(TextureHandle* udimfile); + TextureHandle* resolve_udim(ustring filename, float s, float t); TextureHandle* resolve_udim(TextureHandle* udimfile, Perthread* thread_info, - float s, float t) override; + float s, float t); void inventory_udim(ustring udimpattern, std::vector& filenames, - int& nutiles, int& nvtiles) override; + int& nutiles, int& nvtiles); void inventory_udim(TextureHandle* udimfile, Perthread* thread_info, std::vector& filenames, int& nutiles, - int& nvtiles) override; + int& nvtiles); - bool has_error() const override; - std::string geterror(bool clear = true) const override; - std::string getstats(int level = 1, bool icstats = true) const override; - void reset_stats() override; + bool has_error() const; + std::string geterror(bool clear = true) const; + std::string getstats(int level = 1, bool icstats = true) const; + void reset_stats(); - void invalidate(ustring filename, bool force) override; - void invalidate_all(bool force = false) override; - void close(ustring filename) override; - void close_all() override; + void invalidate(ustring filename, bool force); + void invalidate_all(bool force = false); + void close(ustring filename); + void close_all(); - void operator delete(void* todel) { ::delete ((char*)todel); } + // void operator delete(void* todel) { ::delete ((char*)todel); } typedef bool (*wrap_impl)(int& coord, int origin, int width); /// Return an opaque, non-owning pointer to the underlying ImageCache /// (if there is one). - std::shared_ptr imagecache() const override - { - return m_imagecache_sp; - } + std::shared_ptr imagecache() const { return m_imagecache_sp; } -private: - typedef ImageCacheTileRef TileRef; - typedef ImageCachePerThreadInfo PerThreadInfo; + // private: + using TileRef = ImageCacheTileRef; + using PerThreadInfo = ImageCachePerThreadInfo; void init(); @@ -594,9 +551,6 @@ TextureSystemImpl::st_to_texel(float s, float t, TextureFile& texturefile, } - -} // end namespace pvt - OIIO_NAMESPACE_END #endif // OPENIMAGEIO_TEXTURE_PVT_H diff --git a/src/libtexture/texturesys.cpp b/src/libtexture/texturesys.cpp index 8d5400ce6b..9770b6a95e 100644 --- a/src/libtexture/texturesys.cpp +++ b/src/libtexture/texturesys.cpp @@ -81,6 +81,26 @@ static const OIIO_SIMD4_ALIGN vbool4 channel_masks[5] = { } // end anonymous namespace + +void +TextureSystem::impl_deleter(TextureSystemImpl* todel) +{ + delete todel; +} + + + +TextureSystem::TextureSystem(std::shared_ptr imagecache) + : m_impl(new TextureSystemImpl(imagecache), &impl_deleter) +{ +} + + + +TextureSystem::~TextureSystem() {} + + + std::shared_ptr TextureSystem::create(bool shared, std::shared_ptr imagecache) { @@ -96,7 +116,7 @@ TextureSystem::create(bool shared, std::shared_ptr imagecache) // as the shared one. spin_lock guard(shared_texturesys_mutex); if (!shared_texturesys) - shared_texturesys = std::make_shared( + shared_texturesys = std::make_shared( ImageCache::create(true)); return shared_texturesys; } @@ -107,8 +127,8 @@ TextureSystem::create(bool shared, std::shared_ptr imagecache) imagecache = ImageCache::create(false); own_ic = true; } - auto ts = std::make_shared(imagecache); - ts->m_imagecache_owner = own_ic; + auto ts = std::make_shared(imagecache); + ts->m_impl->m_imagecache_owner = own_ic; OIIO_PRAGMA_WARNING_POP return ts; } @@ -121,8 +141,8 @@ TextureSystem::destroy(std::shared_ptr& ts, { if (!ts) return; - TextureSystemImpl* impl = (TextureSystemImpl*)ts.get(); if (teardown_imagecache) { + TextureSystemImpl* impl = ts->m_impl.get(); if (impl->m_imagecache_owner) ImageCache::destroy(impl->m_imagecache_sp, true); impl->m_imagecache = nullptr; @@ -134,7 +154,346 @@ TextureSystem::destroy(std::shared_ptr& ts, -namespace pvt { // namespace pvt +TextureSystem::Perthread* +TextureSystem::get_perthread_info(Perthread* thread_info) +{ + return m_impl->get_perthread_info( + (TextureSystemImpl::Perthread*)thread_info); +} + + + +TextureSystem::Perthread* +TextureSystem::create_thread_info() +{ + return m_impl->create_thread_info(); +} + + + +void +TextureSystem::destroy_thread_info(Perthread* threadinfo) +{ + m_impl->destroy_thread_info((TextureSystemImpl::Perthread*)threadinfo); +} + + + +bool +TextureSystem::attribute(string_view name, TypeDesc type, const void* val) +{ + return m_impl->attribute(name, type, val); +} + + + +TypeDesc +TextureSystem::getattributetype(string_view name) const +{ + return m_impl->getattributetype(name); +} + + + +bool +TextureSystem::getattribute(string_view name, TypeDesc type, void* val) const +{ + return m_impl->getattribute(name, type, val); +} + + + +TextureSystem::TextureHandle* +TextureSystem::get_texture_handle(ustring filename, Perthread* thread_info, + const TextureOpt* options) +{ + return m_impl->get_texture_handle( + filename, (TextureSystemImpl::Perthread*)thread_info, options); +} + + + +bool +TextureSystem::good(TextureHandle* texture_handle) +{ + return m_impl->good(texture_handle); +} + + + +ustring +TextureSystem::filename_from_handle(TextureHandle* handle) +{ + return m_impl->filename_from_handle(handle); +} + + + +int +TextureSystem::get_colortransform_id(ustring fromspace, ustring tospace) const +{ + return m_impl->get_colortransform_id(fromspace, tospace); +} + + +int +TextureSystem::get_colortransform_id(ustringhash fromspace, + ustringhash tospace) const +{ + return m_impl->get_colortransform_id(fromspace, tospace); +} + + + +bool +TextureSystem::texture(ustring filename, TextureOpt& options, float s, float t, + float dsdx, float dtdx, float dsdy, float dtdy, + int nchannels, float* result, float* dresultds, + float* dresultdt) +{ + return m_impl->texture(filename, options, s, t, dsdx, dtdx, dsdy, dtdy, + nchannels, result, dresultds, dresultdt); +} + + +bool +TextureSystem::texture(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, float s, float t, float dsdx, + float dtdx, float dsdy, float dtdy, int nchannels, + float* result, float* dresultds, float* dresultdt) +{ + return m_impl->texture(texture_handle, thread_info, options, s, t, dsdx, + dtdx, dsdy, dtdy, nchannels, result, dresultds, + dresultdt); +} + + +bool +TextureSystem::texture(ustring filename, TextureOptBatch& options, + Tex::RunMask mask, const float* s, const float* t, + const float* dsdx, const float* dtdx, const float* dsdy, + const float* dtdy, int nchannels, float* result, + float* dresultds, float* dresultdt) +{ + return m_impl->texture(filename, options, mask, s, t, dsdx, dtdx, dsdy, + dtdy, nchannels, result, dresultds, dresultdt); +} + + +bool +TextureSystem::texture(TextureHandle* texture_handle, Perthread* thread_info, + TextureOptBatch& options, Tex::RunMask mask, + const float* s, const float* t, const float* dsdx, + const float* dtdx, const float* dsdy, const float* dtdy, + int nchannels, float* result, float* dresultds, + float* dresultdt) +{ + return m_impl->texture(texture_handle, thread_info, options, mask, s, t, + dsdx, dtdx, dsdy, dtdy, nchannels, result, dresultds, + dresultdt); +} + + + +std::string +TextureSystem::resolve_filename(const std::string& filename) const +{ + return m_impl->resolve_filename(filename); +} + + + +bool +TextureSystem::get_texture_info(ustring filename, int subimage, + ustring dataname, TypeDesc datatype, void* data) +{ + return m_impl->get_texture_info(filename, subimage, dataname, datatype, + data); +} + + +bool +TextureSystem::get_texture_info(TextureHandle* texture_handle, + Perthread* thread_info, int subimage, + ustring dataname, TypeDesc datatype, void* data) +{ + return m_impl->get_texture_info(texture_handle, thread_info, subimage, + dataname, datatype, data); +} + + +bool +TextureSystem::get_imagespec(ustring filename, int subimage, ImageSpec& spec) +{ + return m_impl->get_imagespec(filename, subimage, spec); +} + + +bool +TextureSystem::get_imagespec(TextureHandle* texture_handle, + Perthread* thread_info, int subimage, + ImageSpec& spec) +{ + return m_impl->get_imagespec(texture_handle, thread_info, subimage, spec); +} + + +const ImageSpec* +TextureSystem::imagespec(ustring filename, int subimage) +{ + return m_impl->imagespec(filename, subimage); +} + + +const ImageSpec* +TextureSystem::imagespec(TextureHandle* texture_handle, Perthread* thread_info, + int subimage) +{ + return m_impl->imagespec(texture_handle, thread_info, subimage); +} + + +bool +TextureSystem::get_texels(ustring filename, TextureOpt& options, int miplevel, + int xbegin, int xend, int ybegin, int yend, + int zbegin, int zend, int chbegin, int chend, + TypeDesc format, void* result) +{ + return m_impl->get_texels(filename, options, miplevel, xbegin, xend, ybegin, + yend, zbegin, zend, chbegin, chend, format, + result); +} + + +bool +TextureSystem::get_texels(TextureHandle* texture_handle, Perthread* thread_info, + TextureOpt& options, int miplevel, int xbegin, + int xend, int ybegin, int yend, int zbegin, int zend, + int chbegin, int chend, TypeDesc format, void* result) +{ + return m_impl->get_texels(texture_handle, thread_info, options, miplevel, + xbegin, xend, ybegin, yend, zbegin, zend, chbegin, + chend, format, result); +} + + + +bool +TextureSystem::is_udim(ustring filename) +{ + return m_impl->is_udim(filename); +} + + +bool +TextureSystem::is_udim(TextureHandle* udimfile) +{ + return m_impl->is_udim(udimfile); +} + + + +TextureSystem::TextureHandle* +TextureSystem::resolve_udim(ustring udimpattern, float s, float t) +{ + return m_impl->resolve_udim(udimpattern, s, t); +} + + +TextureSystem::TextureHandle* +TextureSystem::resolve_udim(TextureHandle* udimfile, Perthread* thread_info, + float s, float t) +{ + return m_impl->resolve_udim(udimfile, thread_info, s, t); +} + + + +void +TextureSystem::inventory_udim(ustring udimpattern, + std::vector& filenames, int& nutiles, + int& nvtiles) +{ + m_impl->inventory_udim(udimpattern, filenames, nutiles, nvtiles); +} + + +void +TextureSystem::inventory_udim(TextureHandle* udimfile, Perthread* thread_info, + std::vector& filenames, int& nutiles, + int& nvtiles) +{ + m_impl->inventory_udim(udimfile, thread_info, filenames, nutiles, nvtiles); +} + + + +void +TextureSystem::invalidate(ustring filename, bool force) +{ + m_impl->invalidate(filename, force); +} + + +void +TextureSystem::invalidate_all(bool force) +{ + m_impl->invalidate_all(force); +} + + + +void +TextureSystem::close(ustring filename) +{ + m_impl->close(filename); +} + + +void +TextureSystem::close_all() +{ + m_impl->close_all(); +} + + + +bool +TextureSystem::has_error() const +{ + return m_impl->has_error(); +} + + +std::string +TextureSystem::geterror(bool clear) const +{ + return m_impl->geterror(clear); +} + + + +std::string +TextureSystem::getstats(int level, bool icstats) const +{ + return m_impl->getstats(level, icstats); +} + + +void +TextureSystem::reset_stats() +{ + m_impl->reset_stats(); +} + + + +std::shared_ptr +TextureSystem::imagecache() const +{ + return m_impl->m_imagecache_sp; +} + EightBitConverter TextureSystemImpl::uchar2float; @@ -145,7 +504,6 @@ EightBitConverter TextureSystemImpl::uchar2float; // result is a valid pixel coordinate, false if black should be used // instead. - bool TextureSystemImpl::wrap_periodic_sharedborder(int& coord, int origin, int width) { @@ -174,6 +532,7 @@ const TextureSystemImpl::wrap_impl TextureSystemImpl::wrap_functions[] = { }; +namespace pvt { simd::vbool4 wrap_black_simd(simd::vint4& coord_, const simd::vint4& origin, @@ -312,12 +671,15 @@ texture_type_name(TexFormat f) } +} // namespace pvt + + TextureSystemImpl::TextureSystemImpl(std::shared_ptr imagecache) : m_id(++txsys_next_id) { - m_imagecache_sp = imagecache; - m_imagecache = (ImageCacheImpl*)m_imagecache_sp.get(); + m_imagecache_sp = std::move(imagecache); + m_imagecache = (ImageCacheImpl*)m_imagecache_sp->m_impl.get(); init(); } @@ -337,7 +699,7 @@ TextureSystemImpl::init() // Allow environment variable to override default options const char* options = getenv("OPENIMAGEIO_TEXTURE_OPTIONS"); if (options) - attribute("options", options); + attribute("options", TypeString, &options); if (do_unit_test_texture) unit_test_texture(); @@ -2449,33 +2811,33 @@ TextureSystemImpl::sample_bilinear( namespace { - // Evaluate Bspline weights for both value and derivatives (if dw is not - // NULL) into w[0..3] and dw[0..3]. This is the canonical version for - // reference, but we don't actually call it, instead favoring the much - // harder to read SIMD versions below. - template - inline void evalBSplineWeights_and_derivs(T* w, T fraction, T* dw = NULL) - { - T one_frac = 1.0 - fraction; - w[0] = T(1.0 / 6.0) * one_frac * one_frac * one_frac; - w[1] = T(2.0 / 3.0) - - T(0.5) * fraction * fraction * (T(2.0) - fraction); - w[2] = T(2.0 / 3.0) - - T(0.5) * one_frac * one_frac * (T(2.0) - one_frac); - w[3] = T(1.0 / 6.0) * fraction * fraction * fraction; - if (dw) { - dw[0] = T(-0.5) * one_frac * one_frac; - dw[1] = T(0.5) * fraction * (T(3.0) * fraction - T(4.0)); - dw[2] = T(-0.5) * one_frac * (T(3.0) * one_frac - T(4.0)); - dw[3] = T(0.5) * fraction * fraction; - } +// Evaluate Bspline weights for both value and derivatives (if dw is not +// NULL) into w[0..3] and dw[0..3]. This is the canonical version for +// reference, but we don't actually call it, instead favoring the much +// harder to read SIMD versions below. +template +inline void +evalBSplineWeights_and_derivs(T* w, T fraction, T* dw = NULL) +{ + T one_frac = 1.0 - fraction; + w[0] = T(1.0 / 6.0) * one_frac * one_frac * one_frac; + w[1] = T(2.0 / 3.0) - T(0.5) * fraction * fraction * (T(2.0) - fraction); + w[2] = T(2.0 / 3.0) - T(0.5) * one_frac * one_frac * (T(2.0) - one_frac); + w[3] = T(1.0 / 6.0) * fraction * fraction * fraction; + if (dw) { + dw[0] = T(-0.5) * one_frac * one_frac; + dw[1] = T(0.5) * fraction * (T(3.0) * fraction - T(4.0)); + dw[2] = T(-0.5) * one_frac * (T(3.0) * one_frac - T(4.0)); + dw[3] = T(0.5) * fraction * fraction; } +} - // Evaluate the 4 Bspline weights (no derivs), returning them as a vfloat4. - // The fraction also comes in as a vfloat4 (assuming the same value in all 4 - // slots). - inline vfloat4 evalBSplineWeights(const vfloat4& fraction) - { +// Evaluate the 4 Bspline weights (no derivs), returning them as a vfloat4. +// The fraction also comes in as a vfloat4 (assuming the same value in all 4 +// slots). +inline vfloat4 +evalBSplineWeights(const vfloat4& fraction) +{ #if 0 // Version that's easy to read and understand: float one_frac = 1.0f - fraction; @@ -2486,24 +2848,25 @@ namespace { w[3] = 0.0f + (1.0f / 6.0f) * fraction * fraction * fraction; return w; #else - // Not as clear, but fastest version I've been able to achieve: - OIIO_SIMD_FLOAT4_CONST4(A, 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, 0.0f); - OIIO_SIMD_FLOAT4_CONST4(B, 1.0f / 6.0f, -0.5f, -0.5f, 1.0f / 6.0f); - OIIO_SIMD_FLOAT4_CONST4(om1m1o, 1.0f, -1.0f, -1.0f, 1.0f); - OIIO_SIMD_FLOAT4_CONST4(z22z, 0.0f, 2.0f, 2.0f, 0.0f); - simd::vfloat4 one_frac = vfloat4::One() - fraction; - simd::vfloat4 ofof = AxBxAyBy(one_frac, - fraction); // 1-frac, frac, 1-frac, frac - simd::vfloat4 C = (*(vfloat4*)&om1m1o) * ofof + (*(vfloat4*)&z22z); - return (*(vfloat4*)&A) + (*(vfloat4*)&B) * ofof * ofof * C; + // Not as clear, but fastest version I've been able to achieve: + OIIO_SIMD_FLOAT4_CONST4(A, 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, 0.0f); + OIIO_SIMD_FLOAT4_CONST4(B, 1.0f / 6.0f, -0.5f, -0.5f, 1.0f / 6.0f); + OIIO_SIMD_FLOAT4_CONST4(om1m1o, 1.0f, -1.0f, -1.0f, 1.0f); + OIIO_SIMD_FLOAT4_CONST4(z22z, 0.0f, 2.0f, 2.0f, 0.0f); + simd::vfloat4 one_frac = vfloat4::One() - fraction; + simd::vfloat4 ofof = AxBxAyBy(one_frac, + fraction); // 1-frac, frac, 1-frac, frac + simd::vfloat4 C = (*(vfloat4*)&om1m1o) * ofof + (*(vfloat4*)&z22z); + return (*(vfloat4*)&A) + (*(vfloat4*)&B) * ofof * ofof * C; #endif - } +} - // Evaluate Bspline weights for both value and derivatives (if dw is not - // NULL), returning the 4 coefficients for each as vfloat4's. - inline void evalBSplineWeights_and_derivs(simd::vfloat4* w, float fraction, - simd::vfloat4* dw = NULL) - { +// Evaluate Bspline weights for both value and derivatives (if dw is not +// NULL), returning the 4 coefficients for each as vfloat4's. +inline void +evalBSplineWeights_and_derivs(simd::vfloat4* w, float fraction, + simd::vfloat4* dw = NULL) +{ #if 0 // Version that's easy to read and understand: float one_frac = 1.0f - fraction; @@ -2518,21 +2881,21 @@ namespace { (*dw)[3] = 0.5f * fraction * (1.0f * fraction - 0.0f); } #else - // Not as clear, but fastest version I've been able to achieve: - OIIO_SIMD_FLOAT4_CONST4(A, 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, 0.0f); - OIIO_SIMD_FLOAT4_CONST4(B, 1.0f / 6.0f, -0.5f, -0.5f, 1.0f / 6.0f); - float one_frac = 1.0f - fraction; - simd::vfloat4 ofof(one_frac, fraction, one_frac, fraction); - simd::vfloat4 C(one_frac, 2.0f - fraction, 2.0f - one_frac, fraction); - *w = (*(vfloat4*)&A) + (*(vfloat4*)&B) * ofof * ofof * C; - if (dw) { - const simd::vfloat4 D(-0.5f, 0.5f, -0.5f, 0.5f); - const simd::vfloat4 E(1.0f, 3.0f, 3.0f, 1.0f); - const simd::vfloat4 F(0.0f, 4.0f, 4.0f, 0.0f); - *dw = D * ofof * (E * ofof - F); - } -#endif + // Not as clear, but fastest version I've been able to achieve: + OIIO_SIMD_FLOAT4_CONST4(A, 0.0f, 2.0f / 3.0f, 2.0f / 3.0f, 0.0f); + OIIO_SIMD_FLOAT4_CONST4(B, 1.0f / 6.0f, -0.5f, -0.5f, 1.0f / 6.0f); + float one_frac = 1.0f - fraction; + simd::vfloat4 ofof(one_frac, fraction, one_frac, fraction); + simd::vfloat4 C(one_frac, 2.0f - fraction, 2.0f - one_frac, fraction); + *w = (*(vfloat4*)&A) + (*(vfloat4*)&B) * ofof * ofof * C; + if (dw) { + const simd::vfloat4 D(-0.5f, 0.5f, -0.5f, 0.5f); + const simd::vfloat4 E(1.0f, 3.0f, 3.0f, 1.0f); + const simd::vfloat4 F(0.0f, 4.0f, 4.0f, 0.0f); + *dw = D * ofof * (E * ofof - F); } +#endif +} } // anonymous namespace @@ -3090,8 +3453,6 @@ TextureSystemImpl::unit_test_texture() } } -} // end namespace pvt - void @@ -3113,9 +3474,6 @@ TextureSystem::unit_test_hash() auto imagecache = ImageCache::create(); // Set up the ImageCacheFiles outside of the timing loop - using OIIO::pvt::ImageCacheFile; - using OIIO::pvt::ImageCacheFileRef; - using OIIO::pvt::ImageCacheImpl; std::vector icf; for (int f = 0; f < nfiles; ++f) { ustring filename = ustring::fmtformat("{:06}.tif", f); @@ -3129,7 +3487,7 @@ TextureSystem::unit_test_hash() for (int f = 0; f < nfiles; ++f) { for (int y = 0; y < res; y += tilesize) { for (int x = 0; x < res; x += tilesize, ++i) { - OIIO::pvt::TileID id(*icf[f], 0, 0, x, y, 0, 0, 1); + TileID id(*icf[f], 0, 0, x, y, 0, 0, 1); size_t h = id.hash(); hh += h; } @@ -3147,7 +3505,7 @@ TextureSystem::unit_test_hash() for (int f = 0; f < nfiles; ++f) { for (int y = 0; y < res; y += tilesize) { for (int x = 0; x < res; x += tilesize, ++i) { - OIIO::pvt::TileID id(*icf[f], 0, 0, x, y, 0, 0, 1); + TileID id(*icf[f], 0, 0, x, y, 0, 0, 1); size_t h = id.hash(); ++fourbits[h & 0xf]; ++eightbits[h & 0xff];