blob: ec503d7066d9e04a3830d668c0afe7fb83a25b21 [file] [log] [blame]
robertphillips@google.com7d501ab2012-06-21 21:09:06 +00001/*
2 * Copyright 2012 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 "GrSurface.h"
bsalomonf276ac52015-10-09 13:36:42 -07009#include "GrContext.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040010#include "GrOpList.h"
Robert Phillipsc4f0a822017-06-13 08:11:36 -040011#include "GrRenderTarget.h"
Robert Phillipsf8e25022017-11-08 15:24:31 -050012#include "GrResourceProvider.h"
bsalomonafbf2d62014-09-30 12:18:44 -070013#include "GrSurfacePriv.h"
Mike Reed84dd8572017-03-08 22:21:00 -050014#include "GrTexture.h"
robertphillips@google.com7d501ab2012-06-21 21:09:06 +000015
Brian Osman3b655982017-03-07 16:58:08 -050016#include "SkGr.h"
Robert Phillipsb4460882016-11-17 14:43:51 -050017#include "SkMathPriv.h"
commit-bot@chromium.org6c5d9a12013-09-30 18:05:43 +000018
Robert Phillipsb4460882016-11-17 14:43:51 -050019size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2) {
robertphillips6e83ac72015-08-13 05:19:14 -070020 size_t size;
21
Robert Phillipsf8e25022017-11-08 15:24:31 -050022 int width = useNextPow2
23 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(desc.fWidth))
24 : desc.fWidth;
25 int height = useNextPow2
26 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(desc.fHeight))
27 : desc.fHeight;
Robert Phillipsb4460882016-11-17 14:43:51 -050028
robertphillips6e83ac72015-08-13 05:19:14 -070029 bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
30 if (isRenderTarget) {
31 // We own one color value for each MSAA sample.
32 int colorValuesPerPixel = SkTMax(1, desc.fSampleCnt);
33 if (desc.fSampleCnt) {
34 // Worse case, we own the resolve buffer so that is one more sample per pixel.
35 colorValuesPerPixel += 1;
36 }
37 SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
Robert Phillipsb4460882016-11-17 14:43:51 -050038 size_t colorBytes = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
robertphillips4c56b9f2016-08-17 08:02:51 -070039
Robert Phillipsd6214d42016-11-07 08:23:48 -050040 // This would be a nice assert to have (i.e., we aren't creating 0 width/height surfaces).
41 // Unfortunately Chromium seems to want to do this.
42 //SkASSERT(colorBytes > 0);
43
44 size = colorValuesPerPixel * colorBytes;
45 size += colorBytes/3; // in case we have to mipmap
robertphillips6e83ac72015-08-13 05:19:14 -070046 } else {
Robert Phillips92de6312017-05-23 07:43:48 -040047 size = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
robertphillips6e83ac72015-08-13 05:19:14 -070048
49 size += size/3; // in case we have to mipmap
50 }
51
52 return size;
53}
54
Brian Salomonbb5711a2017-05-17 13:49:59 -040055size_t GrSurface::ComputeSize(GrPixelConfig config,
56 int width,
57 int height,
Robert Phillipsd6214d42016-11-07 08:23:48 -050058 int colorSamplesPerPixel,
Greg Daniele252f082017-10-23 16:05:23 -040059 GrMipMapped mipMapped,
Robert Phillipsb4460882016-11-17 14:43:51 -050060 bool useNextPow2) {
Robert Phillipsf8e25022017-11-08 15:24:31 -050061 width = useNextPow2
62 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(width))
63 : width;
64 height = useNextPow2
65 ? SkTMax(GrResourceProvider::kMinScratchTextureSize, GrNextPow2(height))
66 : height;
Robert Phillipsb4460882016-11-17 14:43:51 -050067
Brian Salomonbb5711a2017-05-17 13:49:59 -040068 SkASSERT(kUnknown_GrPixelConfig != config);
Robert Phillips92de6312017-05-23 07:43:48 -040069 size_t colorSize = (size_t)width * height * GrBytesPerPixel(config);
Robert Phillipsd6214d42016-11-07 08:23:48 -050070 SkASSERT(colorSize > 0);
71
72 size_t finalSize = colorSamplesPerPixel * colorSize;
73
Greg Daniele252f082017-10-23 16:05:23 -040074 if (GrMipMapped::kYes == mipMapped) {
Robert Phillipsd6214d42016-11-07 08:23:48 -050075 // We don't have to worry about the mipmaps being a different size than
76 // we'd expect because we never change fDesc.fWidth/fHeight.
77 finalSize += colorSize/3;
78 }
Robert Phillipsd6214d42016-11-07 08:23:48 -050079 return finalSize;
80}
81
bsalomone8d21e82015-07-16 08:23:13 -070082template<typename T> static bool adjust_params(int surfaceWidth,
83 int surfaceHeight,
84 size_t bpp,
85 int* left, int* top, int* width, int* height,
86 T** data,
87 size_t* rowBytes) {
88 if (!*rowBytes) {
89 *rowBytes = *width * bpp;
90 }
91
92 SkIRect subRect = SkIRect::MakeXYWH(*left, *top, *width, *height);
93 SkIRect bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight);
94
95 if (!subRect.intersect(bounds)) {
96 return false;
97 }
98 *data = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(*data) +
99 (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
100
101 *left = subRect.fLeft;
102 *top = subRect.fTop;
103 *width = subRect.width();
104 *height = subRect.height();
105 return true;
106}
107
108bool GrSurfacePriv::AdjustReadPixelParams(int surfaceWidth,
109 int surfaceHeight,
110 size_t bpp,
111 int* left, int* top, int* width, int* height,
112 void** data,
113 size_t* rowBytes) {
114 return adjust_params<void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height, data,
115 rowBytes);
116}
117
118bool GrSurfacePriv::AdjustWritePixelParams(int surfaceWidth,
119 int surfaceHeight,
120 size_t bpp,
121 int* left, int* top, int* width, int* height,
122 const void** data,
123 size_t* rowBytes) {
124 return adjust_params<const void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height,
125 data, rowBytes);
126}
127
128
129//////////////////////////////////////////////////////////////////////////////
130
bsalomon8d034a12014-09-22 12:21:08 -0700131bool GrSurface::hasPendingRead() const {
132 const GrTexture* thisTex = this->asTexture();
133 if (thisTex && thisTex->internalHasPendingRead()) {
134 return true;
135 }
136 const GrRenderTarget* thisRT = this->asRenderTarget();
137 if (thisRT && thisRT->internalHasPendingRead()) {
138 return true;
139 }
140 return false;
141}
142
143bool GrSurface::hasPendingWrite() const {
144 const GrTexture* thisTex = this->asTexture();
145 if (thisTex && thisTex->internalHasPendingWrite()) {
146 return true;
147 }
148 const GrRenderTarget* thisRT = this->asRenderTarget();
149 if (thisRT && thisRT->internalHasPendingWrite()) {
150 return true;
151 }
152 return false;
153}
154
155bool GrSurface::hasPendingIO() const {
156 const GrTexture* thisTex = this->asTexture();
157 if (thisTex && thisTex->internalHasPendingIO()) {
158 return true;
159 }
160 const GrRenderTarget* thisRT = this->asRenderTarget();
161 if (thisRT && thisRT->internalHasPendingIO()) {
162 return true;
163 }
164 return false;
165}
reedde499882015-06-18 13:41:40 -0700166
167void GrSurface::onRelease() {
reedde499882015-06-18 13:41:40 -0700168 this->INHERITED::onRelease();
169}
170
171void GrSurface::onAbandon() {
reedde499882015-06-18 13:41:40 -0700172 this->INHERITED::onAbandon();
173}