1669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com */
8669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
10669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com#include "GrTexture.h"
11aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.com
12669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com#include "GrContext.h"
13c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h"
1405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h"
15aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.com#include "GrRenderTarget.h"
16a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com#include "GrResourceCache.h"
178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
18686bcb871b8425603b9accbf72e27a9309f786d8bsalomon@google.comGrTexture::~GrTexture() {
1949f085dddff10473b6ebf832a974288300224e60bsalomon    if (fRenderTarget.get()) {
20686bcb871b8425603b9accbf72e27a9309f786d8bsalomon@google.com        fRenderTarget.get()->owningTextureDestroyed();
21686bcb871b8425603b9accbf72e27a9309f786d8bsalomon@google.com    }
22686bcb871b8425603b9accbf72e27a9309f786d8bsalomon@google.com}
23686bcb871b8425603b9accbf72e27a9309f786d8bsalomon@google.com
24d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com/**
2515c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com * This method allows us to interrupt the normal deletion process and place
2615c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com * textures back in the texture cache when their ref count goes to zero.
2715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com */
2815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrTexture::internal_dispose() const {
29e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org    if (this->impl()->isSetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit) &&
3049f085dddff10473b6ebf832a974288300224e60bsalomon        this->INHERITED::getContext()) {
3115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com        GrTexture* nonConstThis = const_cast<GrTexture *>(this);
32dcabb05113a732636691abc16d643a091336aea5bsalomon        this->ref(); // restore ref count to initial setting
3315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com
34e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org        nonConstThis->impl()->resetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit);
3515c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com        nonConstThis->INHERITED::getContext()->addExistingTextureToCache(nonConstThis);
3615c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com
37d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        // Note: "this" texture might be freed inside addExistingTextureToCache
38f41f4d22576c95f0e3ddfc87be40fcf4ee34b408robertphillips@google.com        // if it is purged.
3915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com        return;
4015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com    }
4115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com
4215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com    this->INHERITED::internal_dispose();
4315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com}
4415c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com
45e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.orgvoid GrTextureImpl::dirtyMipMaps(bool mipMapsDirty) {
4611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    if (mipMapsDirty) {
4711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        if (kValid_MipMapsStatus == fMipMapsStatus) {
4811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org            fMipMapsStatus = kAllocated_MipMapsStatus;
4911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        }
5011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    } else {
5111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        const bool sizeChanged = kNotAllocated_MipMapsStatus == fMipMapsStatus;
5211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        fMipMapsStatus = kValid_MipMapsStatus;
5311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        if (sizeChanged) {
5411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org            // This must not be called until after changing fMipMapsStatus.
5511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org            this->didChangeGpuMemorySize();
5611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        }
5711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    }
5811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org}
5911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
6011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.orgsize_t GrTexture::gpuMemorySize() const {
61d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon    size_t textureSize;
626e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org
636e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    if (GrPixelConfigIsCompressed(fDesc.fConfig)) {
647ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski        textureSize = GrCompressedFormatDataSize(fDesc.fConfig, fDesc.fWidth, fDesc.fHeight);
65d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon    } else {
66d4cb922ea1a85d381e88975b63664f6c0bf28cdbbsalomon        textureSize = (size_t) fDesc.fWidth * fDesc.fHeight * GrBytesPerPixel(fDesc.fConfig);
676e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    }
686e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org
69e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org    if (this->impl()->hasMipMaps()) {
7011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        // We don't have to worry about the mipmaps being a different size than
7111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        // we'd expect because we never change fDesc.fWidth/fHeight.
7211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        textureSize *= 2;
7311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    }
7411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    return textureSize;
7511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org}
7611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
77669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.combool GrTexture::readPixels(int left, int top, int width, int height,
786f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                           GrPixelConfig config, void* buffer,
790342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                           size_t rowBytes, uint32_t pixelOpsFlags) {
80669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    // go through context so that all necessary flushing occurs
816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    GrContext* context = this->getContext();
826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    if (NULL == context) {
836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        return false;
846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
85669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    return context->readTexturePixels(this,
860342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                      left, top, width, height,
870342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                      config, buffer, rowBytes,
880342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                      pixelOpsFlags);
896f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com}
906f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
916f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrTexture::writePixels(int left, int top, int width, int height,
926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                            GrPixelConfig config, const void* buffer,
930342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                            size_t rowBytes, uint32_t pixelOpsFlags) {
946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    // go through context so that all necessary flushing occurs
956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    GrContext* context = this->getContext();
966f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    if (NULL == context) {
976f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        return;
986f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
996f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    context->writeTexturePixels(this,
1000342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                left, top, width, height,
1010342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                config, buffer, rowBytes,
1020342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                pixelOpsFlags);
103669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com}
104cee661af926cc977addc6e039b7022975a448acebsalomon@google.com
105944bcf0acb78f8f9da01e991f1307629959e338absalomonvoid GrTexture::abandonReleaseCommon() {
106944bcf0acb78f8f9da01e991f1307629959e338absalomon    // In debug builds the resource cache tracks removed/exclusive textures and has an unref'ed ptr.
107944bcf0acb78f8f9da01e991f1307629959e338absalomon    // After abandon() or release() the resource cache will be unreachable (getContext() == NULL).
108944bcf0acb78f8f9da01e991f1307629959e338absalomon    // So we readd the texture to the cache here so that it is removed from the exclusive list and
109944bcf0acb78f8f9da01e991f1307629959e338absalomon    // there is no longer an unref'ed ptr to the texture in the cache.
110944bcf0acb78f8f9da01e991f1307629959e338absalomon    if (this->impl()->isSetFlag((GrTextureFlags)GrTextureImpl::kReturnToCache_FlagBit)) {
111944bcf0acb78f8f9da01e991f1307629959e338absalomon        SkASSERT(!this->wasDestroyed());
112944bcf0acb78f8f9da01e991f1307629959e338absalomon        this->ref();  // restores the ref the resource cache gave up when it marked this exclusive.
113944bcf0acb78f8f9da01e991f1307629959e338absalomon        this->impl()->resetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit);
114944bcf0acb78f8f9da01e991f1307629959e338absalomon        this->getContext()->addExistingTextureToCache(this);
115944bcf0acb78f8f9da01e991f1307629959e338absalomon    }
116944bcf0acb78f8f9da01e991f1307629959e338absalomon}
117944bcf0acb78f8f9da01e991f1307629959e338absalomon
11815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrTexture::onRelease() {
119944bcf0acb78f8f9da01e991f1307629959e338absalomon    this->abandonReleaseCommon();
120e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org    SkASSERT(!this->impl()->isSetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_FlagBit));
121d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    INHERITED::onRelease();
12215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com}
12315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com
124aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.comvoid GrTexture::onAbandon() {
125944bcf0acb78f8f9da01e991f1307629959e338absalomon    this->abandonReleaseCommon();
12649f085dddff10473b6ebf832a974288300224e60bsalomon    if (fRenderTarget.get()) {
127aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.com        fRenderTarget->abandon();
128aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.com    }
129d364554bcfd391c3b6111af8bff963a35ab87ba7robertphillips@google.com    INHERITED::onAbandon();
130aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.com}
131aa5b6730f2658618015ed56ffb5882f15b6f053fbsalomon@google.com
13232716283420df90644c8b8114308f7967aa91d9frobertphillips@google.comvoid GrTexture::validateDesc() const {
13349f085dddff10473b6ebf832a974288300224e60bsalomon    if (this->asRenderTarget()) {
13432716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com        // This texture has a render target
135f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrTextureFlagBit));
13632716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com
13749f085dddff10473b6ebf832a974288300224e60bsalomon        if (this->asRenderTarget()->getStencilBuffer()) {
138f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(0 != (fDesc.fFlags & kNoStencil_GrTextureFlagBit));
13932716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com        } else {
140f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit));
14132716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com        }
14232716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com
143f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fDesc.fSampleCnt == this->asRenderTarget()->numSamples());
14432716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com    } else {
145f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == (fDesc.fFlags & kRenderTarget_GrTextureFlagBit));
146f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit));
147f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fDesc.fSampleCnt);
14832716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com    }
14932716283420df90644c8b8114308f7967aa91d9frobertphillips@google.com}
150a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
151e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
152e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org
1530797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com// These flags need to fit in a GrResourceKey::ResourceFlags so they can be folded into the texture
15446a8600405e678718271f62c5994119b8d3241e9robertphillips@google.com// key
1550797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.comenum TextureFlags {
1560797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    /**
1570797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com     * The kStretchToPOT bit is set when the texture is NPOT and is being repeated but the
1580797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com     * hardware doesn't support that feature.
159a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com     */
1600797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    kStretchToPOT_TextureFlag = 0x1,
1610797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    /**
162b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com     * The kBilerp bit can only be set when the kStretchToPOT flag is set and indicates whether the
163b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com     * stretched texture should be bilerped.
164a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com     */
165b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com     kBilerp_TextureFlag       = 0x2,
166a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com};
167a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
168a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.comnamespace {
1690797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.comGrResourceKey::ResourceFlags get_texture_flags(const GrGpu* gpu,
1700797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                                               const GrTextureParams* params,
1710797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                                               const GrTextureDesc& desc) {
1720797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    GrResourceKey::ResourceFlags flags = 0;
17349f085dddff10473b6ebf832a974288300224e60bsalomon    bool tiled = params && params->isTiled();
174bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    if (tiled && !gpu->caps()->npotTextureTileSupport()) {
175f9dae780c2c46a1f08adbbe8de2faaba091254d4tfarina        if (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight)) {
1760797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com            flags |= kStretchToPOT_TextureFlag;
177b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com            switch(params->filterMode()) {
178b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                case GrTextureParams::kNone_FilterMode:
179b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                    break;
180b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                case GrTextureParams::kBilerp_FilterMode:
181b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                case GrTextureParams::kMipMap_FilterMode:
182b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                    flags |= kBilerp_TextureFlag;
183b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com                    break;
184a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com            }
185a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com        }
186a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com    }
1870797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    return flags;
1880797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}
189a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
1900797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.comGrResourceKey::ResourceType texture_resource_type() {
1910797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    static const GrResourceKey::ResourceType gType = GrResourceKey::GenerateResourceType();
1920797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    return gType;
193a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com}
194709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org
195709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org// FIXME:  This should be refactored with the code in gl/GrGpuGL.cpp.
196709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.orgGrSurfaceOrigin resolve_origin(const GrTextureDesc& desc) {
197709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    // By default, GrRenderTargets are GL's normal orientation so that they
198709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    // can be drawn to by the outside world without the client having
199709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    // to render upside down.
200709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit);
201709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    if (kDefault_GrSurfaceOrigin == desc.fOrigin) {
202709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org        return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
203709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    } else {
204709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org        return desc.fOrigin;
205709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    }
206709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org}
207a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com}
208a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
209e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////
210744998e666073166307d2522847b2536000a7619bsalomonGrTextureImpl::GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
211744998e666073166307d2522847b2536000a7619bsalomon    : INHERITED(gpu, isWrapped, desc)
212744998e666073166307d2522847b2536000a7619bsalomon    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
213744998e666073166307d2522847b2536000a7619bsalomon    this->setScratchKey(ComputeScratchKey(desc));
214744998e666073166307d2522847b2536000a7619bsalomon}
215e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.org
216e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.orgGrResourceKey GrTextureImpl::ComputeKey(const GrGpu* gpu,
217b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com                                    const GrTextureParams* params,
218a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com                                    const GrTextureDesc& desc,
2190797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com                                    const GrCacheID& cacheID) {
2200797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    GrResourceKey::ResourceFlags flags = get_texture_flags(gpu, params, desc);
2210797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    return GrResourceKey(cacheID, texture_resource_type(), flags);
222a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com}
223a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
224e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.orgGrResourceKey GrTextureImpl::ComputeScratchKey(const GrTextureDesc& desc) {
2250797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    GrCacheID::Key idKey;
2260797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    // Instead of a client-provided key of the texture contents we create a key from the
2270797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    // descriptor.
2283cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    GR_STATIC_ASSERT(sizeof(idKey) >= 16);
229f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(desc.fHeight < (1 << 16));
230f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(desc.fWidth < (1 << 16));
2310797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    idKey.fData32[0] = (desc.fWidth) | (desc.fHeight << 16);
2320797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    idKey.fData32[1] = desc.fConfig | desc.fSampleCnt << 16;
2330797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    idKey.fData32[2] = desc.fFlags;
234709906b74dc0179609e9f1455dc6e9e13675c0fasenorblanco@chromium.org    idKey.fData32[3] = resolve_origin(desc);    // Only needs 2 bits actually
2353cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    static const int kPadSize = sizeof(idKey) - 16;
2363cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    GR_STATIC_ASSERT(kPadSize >= 0);
2373cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    memset(idKey.fData8 + 16, 0, kPadSize);
2380797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com
2390797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    GrCacheID cacheID(GrResourceKey::ScratchDomain(), idKey);
2400797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    return GrResourceKey(cacheID, texture_resource_type(), 0);
241a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com}
242a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
243e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.orgbool GrTextureImpl::NeedsResizing(const GrResourceKey& key) {
2440797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com    return SkToBool(key.getResourceFlags() & kStretchToPOT_TextureFlag);
245a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com}
246a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com
247e49157f0838c615b10da0ef2b297c742da662e34commit-bot@chromium.orgbool GrTextureImpl::NeedsBilerp(const GrResourceKey& key) {
248b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com    return SkToBool(key.getResourceFlags() & kBilerp_TextureFlag);
249a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com}
250