|  | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //    http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | #ifndef sw_Surface_hpp | 
|  | #define sw_Surface_hpp | 
|  |  | 
|  | #include "Color.hpp" | 
|  | #include "Main/Config.hpp" | 
|  | #include "Common/Resource.hpp" | 
|  |  | 
|  | namespace sw | 
|  | { | 
|  | class Resource; | 
|  |  | 
|  | template <typename T> struct RectT | 
|  | { | 
|  | RectT() {} | 
|  | RectT(T x0i, T y0i, T x1i, T y1i) : x0(x0i), y0(y0i), x1(x1i), y1(y1i) {} | 
|  |  | 
|  | void clip(T minX, T minY, T maxX, T maxY) | 
|  | { | 
|  | x0 = clamp(x0, minX, maxX); | 
|  | y0 = clamp(y0, minY, maxY); | 
|  | x1 = clamp(x1, minX, maxX); | 
|  | y1 = clamp(y1, minY, maxY); | 
|  | } | 
|  |  | 
|  | T width() const  { return x1 - x0; } | 
|  | T height() const { return y1 - y0; } | 
|  |  | 
|  | T x0;   // Inclusive | 
|  | T y0;   // Inclusive | 
|  | T x1;   // Exclusive | 
|  | T y1;   // Exclusive | 
|  | }; | 
|  |  | 
|  | typedef RectT<int> Rect; | 
|  | typedef RectT<float> RectF; | 
|  |  | 
|  | template<typename T> struct SliceRectT : public RectT<T> | 
|  | { | 
|  | SliceRectT() : slice(0) {} | 
|  | SliceRectT(const RectT<T>& rect) : RectT<T>(rect), slice(0) {} | 
|  | SliceRectT(const RectT<T>& rect, int s) : RectT<T>(rect), slice(s) {} | 
|  | SliceRectT(T x0, T y0, T x1, T y1, int s) : RectT<T>(x0, y0, x1, y1), slice(s) {} | 
|  | int slice; | 
|  | }; | 
|  |  | 
|  | typedef SliceRectT<int> SliceRect; | 
|  | typedef SliceRectT<float> SliceRectF; | 
|  |  | 
|  | enum Format : unsigned char | 
|  | { | 
|  | FORMAT_NULL, | 
|  |  | 
|  | FORMAT_A8, | 
|  | FORMAT_R8I, | 
|  | FORMAT_R8UI, | 
|  | FORMAT_R8_SNORM, | 
|  | FORMAT_R8, | 
|  | FORMAT_R16I, | 
|  | FORMAT_R16UI, | 
|  | FORMAT_R32I, | 
|  | FORMAT_R32UI, | 
|  | FORMAT_R3G3B2, | 
|  | FORMAT_A8R3G3B2, | 
|  | FORMAT_X4R4G4B4, | 
|  | FORMAT_A4R4G4B4, | 
|  | FORMAT_R4G4B4A4, | 
|  | FORMAT_R5G6B5, | 
|  | FORMAT_R8G8B8, | 
|  | FORMAT_B8G8R8, | 
|  | FORMAT_X8R8G8B8, | 
|  | FORMAT_A8R8G8B8, | 
|  | FORMAT_X8B8G8R8I, | 
|  | FORMAT_X8B8G8R8UI, | 
|  | FORMAT_X8B8G8R8_SNORM, | 
|  | FORMAT_X8B8G8R8, | 
|  | FORMAT_A8B8G8R8I, | 
|  | FORMAT_A8B8G8R8UI, | 
|  | FORMAT_A8B8G8R8_SNORM, | 
|  | FORMAT_A8B8G8R8, | 
|  | FORMAT_SRGB8_X8, | 
|  | FORMAT_SRGB8_A8, | 
|  | FORMAT_X1R5G5B5, | 
|  | FORMAT_A1R5G5B5, | 
|  | FORMAT_R5G5B5A1, | 
|  | FORMAT_G8R8I, | 
|  | FORMAT_G8R8UI, | 
|  | FORMAT_G8R8_SNORM, | 
|  | FORMAT_G8R8, | 
|  | FORMAT_G16R16, | 
|  | FORMAT_G16R16I, | 
|  | FORMAT_G16R16UI, | 
|  | FORMAT_G32R32I, | 
|  | FORMAT_G32R32UI, | 
|  | FORMAT_A2R10G10B10, | 
|  | FORMAT_A2B10G10R10, | 
|  | FORMAT_A2B10G10R10UI, | 
|  | FORMAT_A16B16G16R16, | 
|  | FORMAT_X16B16G16R16I, | 
|  | FORMAT_X16B16G16R16UI, | 
|  | FORMAT_A16B16G16R16I, | 
|  | FORMAT_A16B16G16R16UI, | 
|  | FORMAT_X32B32G32R32I, | 
|  | FORMAT_X32B32G32R32UI, | 
|  | FORMAT_A32B32G32R32I, | 
|  | FORMAT_A32B32G32R32UI, | 
|  | // Paletted formats | 
|  | FORMAT_P8, | 
|  | FORMAT_A8P8, | 
|  | // Compressed formats | 
|  | FORMAT_DXT1, | 
|  | FORMAT_DXT3, | 
|  | FORMAT_DXT5, | 
|  | FORMAT_ATI1, | 
|  | FORMAT_ATI2, | 
|  | FORMAT_ETC1, | 
|  | FORMAT_R11_EAC, | 
|  | FORMAT_SIGNED_R11_EAC, | 
|  | FORMAT_RG11_EAC, | 
|  | FORMAT_SIGNED_RG11_EAC, | 
|  | FORMAT_RGB8_ETC2, | 
|  | FORMAT_SRGB8_ETC2, | 
|  | FORMAT_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, | 
|  | FORMAT_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, | 
|  | FORMAT_RGBA8_ETC2_EAC, | 
|  | FORMAT_SRGB8_ALPHA8_ETC2_EAC, | 
|  | FORMAT_RGBA_ASTC_4x4_KHR, | 
|  | FORMAT_RGBA_ASTC_5x4_KHR, | 
|  | FORMAT_RGBA_ASTC_5x5_KHR, | 
|  | FORMAT_RGBA_ASTC_6x5_KHR, | 
|  | FORMAT_RGBA_ASTC_6x6_KHR, | 
|  | FORMAT_RGBA_ASTC_8x5_KHR, | 
|  | FORMAT_RGBA_ASTC_8x6_KHR, | 
|  | FORMAT_RGBA_ASTC_8x8_KHR, | 
|  | FORMAT_RGBA_ASTC_10x5_KHR, | 
|  | FORMAT_RGBA_ASTC_10x6_KHR, | 
|  | FORMAT_RGBA_ASTC_10x8_KHR, | 
|  | FORMAT_RGBA_ASTC_10x10_KHR, | 
|  | FORMAT_RGBA_ASTC_12x10_KHR, | 
|  | FORMAT_RGBA_ASTC_12x12_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_4x4_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_5x4_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_5x5_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_6x5_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_6x6_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_8x5_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_8x6_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_8x8_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_10x5_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_10x6_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_10x8_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_10x10_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_12x10_KHR, | 
|  | FORMAT_SRGB8_ALPHA8_ASTC_12x12_KHR, | 
|  | // Floating-point formats | 
|  | FORMAT_A16F, | 
|  | FORMAT_R16F, | 
|  | FORMAT_G16R16F, | 
|  | FORMAT_B16G16R16F, | 
|  | FORMAT_X16B16G16R16F, | 
|  | FORMAT_A16B16G16R16F, | 
|  | FORMAT_X16B16G16R16F_UNSIGNED, | 
|  | FORMAT_A32F, | 
|  | FORMAT_R32F, | 
|  | FORMAT_G32R32F, | 
|  | FORMAT_B32G32R32F, | 
|  | FORMAT_X32B32G32R32F, | 
|  | FORMAT_A32B32G32R32F, | 
|  | FORMAT_X32B32G32R32F_UNSIGNED, | 
|  | // Bump map formats | 
|  | FORMAT_V8U8, | 
|  | FORMAT_L6V5U5, | 
|  | FORMAT_Q8W8V8U8, | 
|  | FORMAT_X8L8V8U8, | 
|  | FORMAT_A2W10V10U10, | 
|  | FORMAT_V16U16, | 
|  | FORMAT_A16W16V16U16, | 
|  | FORMAT_Q16W16V16U16, | 
|  | // Luminance formats | 
|  | FORMAT_L8, | 
|  | FORMAT_A4L4, | 
|  | FORMAT_L16, | 
|  | FORMAT_A8L8, | 
|  | FORMAT_L16F, | 
|  | FORMAT_A16L16F, | 
|  | FORMAT_L32F, | 
|  | FORMAT_A32L32F, | 
|  | // Depth/stencil formats | 
|  | FORMAT_D16, | 
|  | FORMAT_D32, | 
|  | FORMAT_D24X8, | 
|  | FORMAT_D24S8, | 
|  | FORMAT_D24FS8, | 
|  | FORMAT_D32F,                 // Quad layout | 
|  | FORMAT_D32FS8,               // Quad layout | 
|  | FORMAT_D32F_COMPLEMENTARY,   // Quad layout, 1 - z | 
|  | FORMAT_D32FS8_COMPLEMENTARY, // Quad layout, 1 - z | 
|  | FORMAT_D32F_LOCKABLE,        // Linear layout | 
|  | FORMAT_D32FS8_TEXTURE,       // Linear layout, no PCF | 
|  | FORMAT_D32F_SHADOW,          // Linear layout, PCF | 
|  | FORMAT_D32FS8_SHADOW,        // Linear layout, PCF | 
|  | FORMAT_DF24S8, | 
|  | FORMAT_DF16S8, | 
|  | FORMAT_INTZ, | 
|  | FORMAT_S8, | 
|  | // Quad layout framebuffer | 
|  | FORMAT_X8G8R8B8Q, | 
|  | FORMAT_A8G8R8B8Q, | 
|  | // YUV formats | 
|  | FORMAT_YV12_BT601, | 
|  | FORMAT_YV12_BT709, | 
|  | FORMAT_YV12_JFIF,    // Full-swing BT.601 | 
|  |  | 
|  | FORMAT_LAST = FORMAT_YV12_JFIF | 
|  | }; | 
|  |  | 
|  | enum Lock | 
|  | { | 
|  | LOCK_UNLOCKED, | 
|  | LOCK_READONLY, | 
|  | LOCK_WRITEONLY, | 
|  | LOCK_READWRITE, | 
|  | LOCK_DISCARD | 
|  | }; | 
|  |  | 
|  | class [[clang::lto_visibility_public]] Surface | 
|  | { | 
|  | private: | 
|  | struct Buffer | 
|  | { | 
|  | friend Surface; | 
|  |  | 
|  | private: | 
|  | void write(int x, int y, int z, const Color<float> &color); | 
|  | void write(int x, int y, const Color<float> &color); | 
|  | void write(void *element, const Color<float> &color); | 
|  | Color<float> read(int x, int y, int z) const; | 
|  | Color<float> read(int x, int y) const; | 
|  | Color<float> read(void *element) const; | 
|  | Color<float> sample(float x, float y, float z) const; | 
|  | Color<float> sample(float x, float y, int layer) const; | 
|  |  | 
|  | void *lockRect(int x, int y, int z, Lock lock); | 
|  | void unlockRect(); | 
|  |  | 
|  | void *buffer; | 
|  | int width; | 
|  | int height; | 
|  | int depth; | 
|  | short border; | 
|  | short samples; | 
|  |  | 
|  | int bytes; | 
|  | int pitchB; | 
|  | int pitchP; | 
|  | int sliceB; | 
|  | int sliceP; | 
|  |  | 
|  | Format format; | 
|  | AtomicInt lock; | 
|  |  | 
|  | bool dirty;   // Sibling internal/external buffer doesn't match. | 
|  | }; | 
|  |  | 
|  | protected: | 
|  | Surface(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); | 
|  | Surface(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0); | 
|  |  | 
|  | public: | 
|  | static Surface *create(int width, int height, int depth, Format format, void *pixels, int pitch, int slice); | 
|  | static Surface *create(Resource *texture, int width, int height, int depth, int border, int samples, Format format, bool lockable, bool renderTarget, int pitchP = 0); | 
|  |  | 
|  | virtual ~Surface() = 0; | 
|  |  | 
|  | inline void *lock(int x, int y, int z, Lock lock, Accessor client, bool internal = false); | 
|  | inline void unlock(bool internal = false); | 
|  | inline int getWidth() const; | 
|  | inline int getHeight() const; | 
|  | inline int getDepth() const; | 
|  | inline int getBorder() const; | 
|  | inline Format getFormat(bool internal = false) const; | 
|  | inline int getPitchB(bool internal = false) const; | 
|  | inline int getPitchP(bool internal = false) const; | 
|  | inline int getSliceB(bool internal = false) const; | 
|  | inline int getSliceP(bool internal = false) const; | 
|  |  | 
|  | void *lockExternal(int x, int y, int z, Lock lock, Accessor client); | 
|  | void unlockExternal(); | 
|  | inline Format getExternalFormat() const; | 
|  | inline int getExternalPitchB() const; | 
|  | inline int getExternalPitchP() const; | 
|  | inline int getExternalSliceB() const; | 
|  | inline int getExternalSliceP() const; | 
|  |  | 
|  | virtual void *lockInternal(int x, int y, int z, Lock lock, Accessor client) = 0; | 
|  | virtual void unlockInternal() = 0; | 
|  | inline Format getInternalFormat() const; | 
|  | inline int getInternalPitchB() const; | 
|  | inline int getInternalPitchP() const; | 
|  | inline int getInternalSliceB() const; | 
|  | inline int getInternalSliceP() const; | 
|  |  | 
|  | void *lockStencil(int x, int y, int front, Accessor client); | 
|  | void unlockStencil(); | 
|  | inline Format getStencilFormat() const; | 
|  | inline int getStencilPitchB() const; | 
|  | inline int getStencilSliceB() const; | 
|  |  | 
|  | void sync();                      // Wait for lock(s) to be released. | 
|  | inline bool isUnlocked() const;   // Only reliable after sync(). | 
|  |  | 
|  | inline int getSamples() const; | 
|  | inline int getMultiSampleCount() const; | 
|  | inline int getSuperSampleCount() const; | 
|  |  | 
|  | bool isEntire(const Rect& rect) const; | 
|  | Rect getRect() const; | 
|  | void clearDepth(float depth, int x0, int y0, int width, int height); | 
|  | void clearStencil(unsigned char stencil, unsigned char mask, int x0, int y0, int width, int height); | 
|  | void fill(const Color<float> &color, int x0, int y0, int width, int height); | 
|  |  | 
|  | Color<float> readExternal(int x, int y, int z) const; | 
|  | Color<float> readExternal(int x, int y) const; | 
|  | Color<float> sampleExternal(float x, float y, float z) const; | 
|  | Color<float> sampleExternal(float x, float y) const; | 
|  | void writeExternal(int x, int y, int z, const Color<float> &color); | 
|  | void writeExternal(int x, int y, const Color<float> &color); | 
|  |  | 
|  | void copyInternal(const Surface* src, int x, int y, float srcX, float srcY, bool filter); | 
|  | void copyInternal(const Surface* src, int x, int y, int z, float srcX, float srcY, float srcZ, bool filter); | 
|  |  | 
|  | enum Edge { TOP, BOTTOM, RIGHT, LEFT }; | 
|  | void copyCubeEdge(Edge dstEdge, Surface *src, Edge srcEdge); | 
|  | void computeCubeCorner(int x0, int y0, int x1, int y1); | 
|  |  | 
|  | bool hasStencil() const; | 
|  | bool hasDepth() const; | 
|  | bool hasPalette() const; | 
|  | bool isRenderTarget() const; | 
|  |  | 
|  | bool hasDirtyContents() const; | 
|  | void markContentsClean(); | 
|  | inline bool isExternalDirty() const; | 
|  | Resource *getResource(); | 
|  |  | 
|  | static int bytes(Format format); | 
|  | static int pitchB(int width, int border, Format format, bool target); | 
|  | static int pitchP(int width, int border, Format format, bool target); | 
|  | static int sliceB(int width, int height, int border, Format format, bool target); | 
|  | static int sliceP(int width, int height, int border, Format format, bool target); | 
|  | static unsigned int size(int width, int height, int depth, int border, int samples, Format format);   // FIXME: slice * depth | 
|  |  | 
|  | static bool isStencil(Format format); | 
|  | static bool isDepth(Format format); | 
|  | static bool hasQuadLayout(Format format); | 
|  | static bool isPalette(Format format); | 
|  |  | 
|  | static bool isFloatFormat(Format format); | 
|  | static bool isUnsignedComponent(Format format, int component); | 
|  | static bool isSRGBreadable(Format format); | 
|  | static bool isSRGBwritable(Format format); | 
|  | static bool isSRGBformat(Format format); | 
|  | static bool isCompressed(Format format); | 
|  | static bool isSignedNonNormalizedInteger(Format format); | 
|  | static bool isUnsignedNonNormalizedInteger(Format format); | 
|  | static bool isNonNormalizedInteger(Format format); | 
|  | static bool isNormalizedInteger(Format format); | 
|  | static int componentCount(Format format); | 
|  |  | 
|  | static void setTexturePalette(unsigned int *palette); | 
|  |  | 
|  | private: | 
|  | sw::Resource *resource; | 
|  |  | 
|  | typedef unsigned char byte; | 
|  | typedef unsigned short word; | 
|  | typedef unsigned int dword; | 
|  | typedef uint64_t qword; | 
|  |  | 
|  | struct DXT1 | 
|  | { | 
|  | word c0; | 
|  | word c1; | 
|  | dword lut; | 
|  | }; | 
|  |  | 
|  | struct DXT3 | 
|  | { | 
|  | qword a; | 
|  |  | 
|  | word c0; | 
|  | word c1; | 
|  | dword lut; | 
|  | }; | 
|  |  | 
|  | struct DXT5 | 
|  | { | 
|  | union | 
|  | { | 
|  | struct | 
|  | { | 
|  | byte a0; | 
|  | byte a1; | 
|  | }; | 
|  |  | 
|  | qword alut;   // Skip first 16 bit | 
|  | }; | 
|  |  | 
|  | word c0; | 
|  | word c1; | 
|  | dword clut; | 
|  | }; | 
|  |  | 
|  | struct ATI2 | 
|  | { | 
|  | union | 
|  | { | 
|  | struct | 
|  | { | 
|  | byte y0; | 
|  | byte y1; | 
|  | }; | 
|  |  | 
|  | qword ylut;   // Skip first 16 bit | 
|  | }; | 
|  |  | 
|  | union | 
|  | { | 
|  | struct | 
|  | { | 
|  | byte x0; | 
|  | byte x1; | 
|  | }; | 
|  |  | 
|  | qword xlut;   // Skip first 16 bit | 
|  | }; | 
|  | }; | 
|  |  | 
|  | struct ATI1 | 
|  | { | 
|  | union | 
|  | { | 
|  | struct | 
|  | { | 
|  | byte r0; | 
|  | byte r1; | 
|  | }; | 
|  |  | 
|  | qword rlut;   // Skip first 16 bit | 
|  | }; | 
|  | }; | 
|  |  | 
|  | static void decodeR8G8B8(Buffer &destination, Buffer &source); | 
|  | static void decodeX1R5G5B5(Buffer &destination, Buffer &source); | 
|  | static void decodeA1R5G5B5(Buffer &destination, Buffer &source); | 
|  | static void decodeX4R4G4B4(Buffer &destination, Buffer &source); | 
|  | static void decodeA4R4G4B4(Buffer &destination, Buffer &source); | 
|  | static void decodeP8(Buffer &destination, Buffer &source); | 
|  |  | 
|  | static void decodeDXT1(Buffer &internal, Buffer &external); | 
|  | static void decodeDXT3(Buffer &internal, Buffer &external); | 
|  | static void decodeDXT5(Buffer &internal, Buffer &external); | 
|  | static void decodeATI1(Buffer &internal, Buffer &external); | 
|  | static void decodeATI2(Buffer &internal, Buffer &external); | 
|  | static void decodeEAC(Buffer &internal, Buffer &external, int nbChannels, bool isSigned); | 
|  | static void decodeETC2(Buffer &internal, Buffer &external, int nbAlphaBits, bool isSRGB); | 
|  | static void decodeASTC(Buffer &internal, Buffer &external, int xSize, int ySize, int zSize, bool isSRGB); | 
|  |  | 
|  | static void update(Buffer &destination, Buffer &source); | 
|  | static void genericUpdate(Buffer &destination, Buffer &source); | 
|  | static void *allocateBuffer(int width, int height, int depth, int border, int samples, Format format); | 
|  | static void memfill4(void *buffer, int pattern, int bytes); | 
|  |  | 
|  | bool identicalFormats() const; | 
|  | Format selectInternalFormat(Format format) const; | 
|  |  | 
|  | void resolve(); | 
|  |  | 
|  | Buffer external; | 
|  | Buffer internal; | 
|  | Buffer stencil; | 
|  |  | 
|  | const bool lockable; | 
|  | const bool renderTarget; | 
|  |  | 
|  | bool dirtyContents;   // Sibling surfaces need updating (mipmaps / cube borders). | 
|  | unsigned int paletteUsed; | 
|  |  | 
|  | static unsigned int *palette;   // FIXME: Not multi-device safe | 
|  | static unsigned int paletteID; | 
|  |  | 
|  | bool hasParent; | 
|  | bool ownExternal; | 
|  | }; | 
|  | } | 
|  |  | 
|  | #undef min | 
|  | #undef max | 
|  |  | 
|  | namespace sw | 
|  | { | 
|  | void *Surface::lock(int x, int y, int z, Lock lock, Accessor client, bool internal) | 
|  | { | 
|  | return internal ? lockInternal(x, y, z, lock, client) : lockExternal(x, y, z, lock, client); | 
|  | } | 
|  |  | 
|  | void Surface::unlock(bool internal) | 
|  | { | 
|  | return internal ? unlockInternal() : unlockExternal(); | 
|  | } | 
|  |  | 
|  | int Surface::getWidth() const | 
|  | { | 
|  | return external.width; | 
|  | } | 
|  |  | 
|  | int Surface::getHeight() const | 
|  | { | 
|  | return external.height; | 
|  | } | 
|  |  | 
|  | int Surface::getDepth() const | 
|  | { | 
|  | return external.depth; | 
|  | } | 
|  |  | 
|  | int Surface::getBorder() const | 
|  | { | 
|  | return internal.border; | 
|  | } | 
|  |  | 
|  | Format Surface::getFormat(bool internal) const | 
|  | { | 
|  | return internal ? getInternalFormat() : getExternalFormat(); | 
|  | } | 
|  |  | 
|  | int Surface::getPitchB(bool internal) const | 
|  | { | 
|  | return internal ? getInternalPitchB() : getExternalPitchB(); | 
|  | } | 
|  |  | 
|  | int Surface::getPitchP(bool internal) const | 
|  | { | 
|  | return internal ? getInternalPitchP() : getExternalPitchP(); | 
|  | } | 
|  |  | 
|  | int Surface::getSliceB(bool internal) const | 
|  | { | 
|  | return internal ? getInternalSliceB() : getExternalSliceB(); | 
|  | } | 
|  |  | 
|  | int Surface::getSliceP(bool internal) const | 
|  | { | 
|  | return internal ? getInternalSliceP() : getExternalSliceP(); | 
|  | } | 
|  |  | 
|  | Format Surface::getExternalFormat() const | 
|  | { | 
|  | return external.format; | 
|  | } | 
|  |  | 
|  | int Surface::getExternalPitchB() const | 
|  | { | 
|  | return external.pitchB; | 
|  | } | 
|  |  | 
|  | int Surface::getExternalPitchP() const | 
|  | { | 
|  | return external.pitchP; | 
|  | } | 
|  |  | 
|  | int Surface::getExternalSliceB() const | 
|  | { | 
|  | return external.sliceB; | 
|  | } | 
|  |  | 
|  | int Surface::getExternalSliceP() const | 
|  | { | 
|  | return external.sliceP; | 
|  | } | 
|  |  | 
|  | Format Surface::getInternalFormat() const | 
|  | { | 
|  | return internal.format; | 
|  | } | 
|  |  | 
|  | int Surface::getInternalPitchB() const | 
|  | { | 
|  | return internal.pitchB; | 
|  | } | 
|  |  | 
|  | int Surface::getInternalPitchP() const | 
|  | { | 
|  | return internal.pitchP; | 
|  | } | 
|  |  | 
|  | int Surface::getInternalSliceB() const | 
|  | { | 
|  | return internal.sliceB; | 
|  | } | 
|  |  | 
|  | int Surface::getInternalSliceP() const | 
|  | { | 
|  | return internal.sliceP; | 
|  | } | 
|  |  | 
|  | Format Surface::getStencilFormat() const | 
|  | { | 
|  | return stencil.format; | 
|  | } | 
|  |  | 
|  | int Surface::getStencilPitchB() const | 
|  | { | 
|  | return stencil.pitchB; | 
|  | } | 
|  |  | 
|  | int Surface::getStencilSliceB() const | 
|  | { | 
|  | return stencil.sliceB; | 
|  | } | 
|  |  | 
|  | int Surface::getSamples() const | 
|  | { | 
|  | return internal.samples; | 
|  | } | 
|  |  | 
|  | int Surface::getMultiSampleCount() const | 
|  | { | 
|  | return sw::min((int)internal.samples, 4); | 
|  | } | 
|  |  | 
|  | int Surface::getSuperSampleCount() const | 
|  | { | 
|  | return internal.samples > 4 ? internal.samples / 4 : 1; | 
|  | } | 
|  |  | 
|  | bool Surface::isUnlocked() const | 
|  | { | 
|  | return external.lock == LOCK_UNLOCKED && | 
|  | internal.lock == LOCK_UNLOCKED && | 
|  | stencil.lock == LOCK_UNLOCKED; | 
|  | } | 
|  |  | 
|  | bool Surface::isExternalDirty() const | 
|  | { | 
|  | return external.buffer && external.buffer != internal.buffer && external.dirty; | 
|  | } | 
|  | } | 
|  |  | 
|  | #endif   // sw_Surface_hpp |