/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrTexturePriv_DEFINED
#define GrTexturePriv_DEFINED

#include "GrTexture.h"

/** Class that adds methods to GrTexture that are only intended for use internal to Skia.
    This class is purely a privileged window into GrTexture. It should never have additional data
    members or virtual methods.
    Non-static methods that are not trivial inlines should be spring-boarded (e.g. declared and
    implemented privately in GrTexture with a inline public method here). */
class GrTexturePriv {
public:
    void dirtyMipMaps(bool mipMapsDirty) {
        fTexture->dirtyMipMaps(mipMapsDirty);
    }

    bool mipMapsAreDirty() const {
        return GrTexture::kValid_MipMapsStatus != fTexture->fMipMapsStatus;
    }

    bool hasMipMaps() const {
        return GrTexture::kNotAllocated_MipMapsStatus != fTexture->fMipMapsStatus;
    }

    void setMaxMipMapLevel(int maxMipMapLevel) const {
        fTexture->fMaxMipMapLevel = maxMipMapLevel;
    }

    int maxMipMapLevel() const {
        return fTexture->fMaxMipMapLevel;
    }

    GrSLType imageStorageType() const {
        if (GrPixelConfigIsSint(fTexture->config())) {
            return kIImageStorage2D_GrSLType;
        } else {
            return kImageStorage2D_GrSLType;
        }
    }

    GrSLType samplerType() const { return fTexture->fSamplerType; }

    /** The filter used is clamped to this value in GrProcessor::TextureSampler. */
    GrSamplerParams::FilterMode highestFilterMode() const { return fTexture->fHighestFilterMode; }

    void setMipColorMode(SkDestinationSurfaceColorMode colorMode) const {
        fTexture->fMipColorMode = colorMode;
    }
    SkDestinationSurfaceColorMode mipColorMode() const { return fTexture->fMipColorMode; }

    static void ComputeScratchKey(const GrSurfaceDesc&, GrScratchKey*);
    static void ComputeScratchKey(GrPixelConfig config, int width, int height,
                                  GrSurfaceOrigin origin, bool isRenderTarget, int sampleCnt,
                                  bool isMipMapped, GrScratchKey* key);


private:
    GrTexturePriv(GrTexture* texture) : fTexture(texture) { }
    GrTexturePriv(const GrTexturePriv& that) : fTexture(that.fTexture) { }
    GrTexturePriv& operator=(const GrTexturePriv&); // unimpl

    // No taking addresses of this type.
    const GrTexturePriv* operator&() const;
    GrTexturePriv* operator&();

    GrTexture* fTexture;

    friend class GrTexture; // to construct/copy this type.
};

inline GrTexturePriv GrTexture::texturePriv() { return GrTexturePriv(this); }

inline const GrTexturePriv GrTexture::texturePriv () const {
    return GrTexturePriv(const_cast<GrTexture*>(this));
}

#endif
