1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/dawn/GrDawnTexture.h"
9
10#include "src/gpu/dawn/GrDawnGpu.h"
11#include "src/gpu/dawn/GrDawnTextureRenderTarget.h"
12#include "src/gpu/dawn/GrDawnUtil.h"
13
14GrDawnTexture::GrDawnTexture(GrDawnGpu* gpu,
15                             SkISize dimensions,
16                             const GrDawnTextureInfo& info,
17                             GrMipmapStatus mipmapStatus)
18        : GrSurface(gpu, dimensions, GrProtected::kNo)
19        , GrTexture(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus)
20        , fInfo(info) {}
21
22sk_sp<GrDawnTexture> GrDawnTexture::Make(GrDawnGpu* gpu, SkISize dimensions,
23                                         wgpu::TextureFormat format,
24                                         GrRenderable renderable, int sampleCnt,
25                                         SkBudgeted budgeted, int mipLevels,
26                                         GrMipmapStatus status) {
27    bool renderTarget = renderable == GrRenderable::kYes;
28    wgpu::TextureDescriptor textureDesc;
29
30    textureDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopySrc |
31                        wgpu::TextureUsage::CopyDst;
32
33    if (renderTarget) {
34        textureDesc.usage |= wgpu::TextureUsage::RenderAttachment;
35    }
36
37    textureDesc.size.width = dimensions.fWidth;
38    textureDesc.size.height = dimensions.fHeight;
39    textureDesc.size.depthOrArrayLayers = 1;
40    textureDesc.format = format;
41    textureDesc.mipLevelCount = std::max(mipLevels, 1);
42    textureDesc.sampleCount = sampleCnt;
43
44    wgpu::Texture tex = gpu->device().CreateTexture(&textureDesc);
45
46    if (!tex) {
47        return nullptr;
48    }
49
50    GrDawnTextureInfo info;
51    info.fTexture = tex;
52    info.fFormat = textureDesc.format;
53    info.fLevelCount = mipLevels;
54    sk_sp<GrDawnTexture> result;
55    if (renderTarget) {
56        result = sk_sp<GrDawnTextureRenderTarget>(new GrDawnTextureRenderTarget(gpu,
57                                                                                dimensions,
58                                                                                sampleCnt,
59                                                                                info,
60                                                                                status));
61    } else {
62        result = sk_sp<GrDawnTexture>(
63                new GrDawnTexture(gpu, dimensions, info, status));
64    }
65    result->registerWithCache(budgeted);
66    return result;
67}
68
69GrBackendFormat GrDawnTexture::backendFormat() const {
70    return GrBackendFormat::MakeDawn(fInfo.fFormat);
71}
72
73sk_sp<GrDawnTexture> GrDawnTexture::MakeWrapped(GrDawnGpu* gpu, SkISize dimensions,
74                                                GrRenderable renderable, int sampleCnt,
75                                                GrWrapCacheable cacheable, GrIOType ioType,
76                                                const GrDawnTextureInfo& info) {
77    sk_sp<GrDawnTexture> tex;
78    GrMipmapStatus status = info.fLevelCount > 1 ? GrMipmapStatus::kValid
79                                                 : GrMipmapStatus::kNotAllocated;
80    if (GrRenderable::kYes == renderable) {
81        tex = sk_sp<GrDawnTexture>(new GrDawnTextureRenderTarget(
82                gpu, dimensions, sampleCnt, info, status));
83    } else {
84        tex = sk_sp<GrDawnTexture>(
85                new GrDawnTexture(gpu, dimensions, info, status));
86    }
87    tex->registerWithCacheWrapped(cacheable);
88    if (ioType == kRead_GrIOType) {
89      tex->setReadOnly();
90    }
91    return tex;
92}
93
94GrDawnTexture::~GrDawnTexture() {
95}
96
97GrDawnGpu* GrDawnTexture::getDawnGpu() const {
98    SkASSERT(!this->wasDestroyed());
99    return static_cast<GrDawnGpu*>(this->getGpu());
100}
101
102void GrDawnTexture::onRelease() {
103    INHERITED::onRelease();
104}
105
106void GrDawnTexture::onAbandon() {
107    INHERITED::onAbandon();
108}
109
110GrBackendTexture GrDawnTexture::getBackendTexture() const {
111    return GrBackendTexture(this->width(), this->height(), fInfo);
112}
113