blob: 635e74e49c89c23b824afecfd06b4c2bf7c3a843 [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"
bsalomonafbf2d62014-09-30 12:18:44 -070011#include "GrSurfacePriv.h"
Mike Reed84dd8572017-03-08 22:21:00 -050012#include "GrTexture.h"
robertphillips@google.com7d501ab2012-06-21 21:09:06 +000013
Brian Osman3b655982017-03-07 16:58:08 -050014#include "SkGr.h"
Robert Phillipsb4460882016-11-17 14:43:51 -050015#include "SkMathPriv.h"
commit-bot@chromium.org6c5d9a12013-09-30 18:05:43 +000016
Robert Phillipsb4460882016-11-17 14:43:51 -050017size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2) {
robertphillips6e83ac72015-08-13 05:19:14 -070018 size_t size;
19
Robert Phillipsb4460882016-11-17 14:43:51 -050020 int width = useNextPow2 ? GrNextPow2(desc.fWidth) : desc.fWidth;
21 int height = useNextPow2 ? GrNextPow2(desc.fHeight) : desc.fHeight;
22
robertphillips6e83ac72015-08-13 05:19:14 -070023 bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
24 if (isRenderTarget) {
25 // We own one color value for each MSAA sample.
26 int colorValuesPerPixel = SkTMax(1, desc.fSampleCnt);
27 if (desc.fSampleCnt) {
28 // Worse case, we own the resolve buffer so that is one more sample per pixel.
29 colorValuesPerPixel += 1;
30 }
31 SkASSERT(kUnknown_GrPixelConfig != desc.fConfig);
Robert Phillipsb4460882016-11-17 14:43:51 -050032 size_t colorBytes = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
robertphillips4c56b9f2016-08-17 08:02:51 -070033
Robert Phillipsd6214d42016-11-07 08:23:48 -050034 // This would be a nice assert to have (i.e., we aren't creating 0 width/height surfaces).
35 // Unfortunately Chromium seems to want to do this.
36 //SkASSERT(colorBytes > 0);
37
38 size = colorValuesPerPixel * colorBytes;
39 size += colorBytes/3; // in case we have to mipmap
robertphillips6e83ac72015-08-13 05:19:14 -070040 } else {
Robert Phillips92de6312017-05-23 07:43:48 -040041 size = (size_t) width * height * GrBytesPerPixel(desc.fConfig);
robertphillips6e83ac72015-08-13 05:19:14 -070042
43 size += size/3; // in case we have to mipmap
44 }
45
46 return size;
47}
48
Brian Salomonbb5711a2017-05-17 13:49:59 -040049size_t GrSurface::ComputeSize(GrPixelConfig config,
50 int width,
51 int height,
Robert Phillipsd6214d42016-11-07 08:23:48 -050052 int colorSamplesPerPixel,
Robert Phillipsb4460882016-11-17 14:43:51 -050053 bool hasMIPMaps,
54 bool useNextPow2) {
Brian Salomonbb5711a2017-05-17 13:49:59 -040055 width = useNextPow2 ? GrNextPow2(width) : width;
56 height = useNextPow2 ? GrNextPow2(height) : height;
Robert Phillipsb4460882016-11-17 14:43:51 -050057
Brian Salomonbb5711a2017-05-17 13:49:59 -040058 SkASSERT(kUnknown_GrPixelConfig != config);
Robert Phillips92de6312017-05-23 07:43:48 -040059 size_t colorSize = (size_t)width * height * GrBytesPerPixel(config);
Robert Phillipsd6214d42016-11-07 08:23:48 -050060 SkASSERT(colorSize > 0);
61
62 size_t finalSize = colorSamplesPerPixel * colorSize;
63
64 if (hasMIPMaps) {
65 // We don't have to worry about the mipmaps being a different size than
66 // we'd expect because we never change fDesc.fWidth/fHeight.
67 finalSize += colorSize/3;
68 }
Robert Phillipsd6214d42016-11-07 08:23:48 -050069 return finalSize;
70}
71
bsalomone8d21e82015-07-16 08:23:13 -070072template<typename T> static bool adjust_params(int surfaceWidth,
73 int surfaceHeight,
74 size_t bpp,
75 int* left, int* top, int* width, int* height,
76 T** data,
77 size_t* rowBytes) {
78 if (!*rowBytes) {
79 *rowBytes = *width * bpp;
80 }
81
82 SkIRect subRect = SkIRect::MakeXYWH(*left, *top, *width, *height);
83 SkIRect bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight);
84
85 if (!subRect.intersect(bounds)) {
86 return false;
87 }
88 *data = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(*data) +
89 (subRect.fTop - *top) * *rowBytes + (subRect.fLeft - *left) * bpp);
90
91 *left = subRect.fLeft;
92 *top = subRect.fTop;
93 *width = subRect.width();
94 *height = subRect.height();
95 return true;
96}
97
98bool GrSurfacePriv::AdjustReadPixelParams(int surfaceWidth,
99 int surfaceHeight,
100 size_t bpp,
101 int* left, int* top, int* width, int* height,
102 void** data,
103 size_t* rowBytes) {
104 return adjust_params<void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height, data,
105 rowBytes);
106}
107
108bool GrSurfacePriv::AdjustWritePixelParams(int surfaceWidth,
109 int surfaceHeight,
110 size_t bpp,
111 int* left, int* top, int* width, int* height,
112 const void** data,
113 size_t* rowBytes) {
114 return adjust_params<const void>(surfaceWidth, surfaceHeight, bpp, left, top, width, height,
115 data, rowBytes);
116}
117
118
119//////////////////////////////////////////////////////////////////////////////
120
bsalomon8d034a12014-09-22 12:21:08 -0700121bool GrSurface::hasPendingRead() const {
122 const GrTexture* thisTex = this->asTexture();
123 if (thisTex && thisTex->internalHasPendingRead()) {
124 return true;
125 }
126 const GrRenderTarget* thisRT = this->asRenderTarget();
127 if (thisRT && thisRT->internalHasPendingRead()) {
128 return true;
129 }
130 return false;
131}
132
133bool GrSurface::hasPendingWrite() const {
134 const GrTexture* thisTex = this->asTexture();
135 if (thisTex && thisTex->internalHasPendingWrite()) {
136 return true;
137 }
138 const GrRenderTarget* thisRT = this->asRenderTarget();
139 if (thisRT && thisRT->internalHasPendingWrite()) {
140 return true;
141 }
142 return false;
143}
144
145bool GrSurface::hasPendingIO() const {
146 const GrTexture* thisTex = this->asTexture();
147 if (thisTex && thisTex->internalHasPendingIO()) {
148 return true;
149 }
150 const GrRenderTarget* thisRT = this->asRenderTarget();
151 if (thisRT && thisRT->internalHasPendingIO()) {
152 return true;
153 }
154 return false;
155}
reedde499882015-06-18 13:41:40 -0700156
157void GrSurface::onRelease() {
reedde499882015-06-18 13:41:40 -0700158 this->INHERITED::onRelease();
159}
160
161void GrSurface::onAbandon() {
reedde499882015-06-18 13:41:40 -0700162 this->INHERITED::onAbandon();
163}