Remove viewport from GrGLRenderTarget.

Change-Id: Id69d8dbe60a38dda2c4c14b02ddeebf230f9299a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/215522
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2019-05-22 16:29:12 -04:00 committed by Skia Commit-Bot
parent 550868a2b2
commit acd66b4946
6 changed files with 56 additions and 86 deletions

View File

@ -1686,9 +1686,7 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
static constexpr uint32_t kZero = 0;
GL_CALL(ClearTexImage(tex->textureID(), 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, &kZero));
} else {
GrGLIRect viewport;
this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, &viewport,
kDst_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, kDst_TempFBOTarget);
this->disableScissor();
this->disableWindowRectangles();
this->flushColorWrite(true);
@ -1939,15 +1937,14 @@ sk_sp<GrGpuBuffer> GrGLGpu::onCreateBuffer(size_t size, GrGpuBufferType intended
return GrGLBuffer::Make(this, size, intendedType, accessPattern, data);
}
void GrGLGpu::flushScissor(const GrScissorState& scissorState,
const GrGLIRect& rtViewport,
void GrGLGpu::flushScissor(const GrScissorState& scissorState, int rtWidth, int rtHeight,
GrSurfaceOrigin rtOrigin) {
if (scissorState.enabled()) {
GrGLIRect scissor;
scissor.setRelativeTo(rtViewport, scissorState.rect(), rtOrigin);
scissor.setRelativeTo(rtHeight, scissorState.rect(), rtOrigin);
// if the scissor fully contains the viewport then we fall through and
// disable the scissor test.
if (!scissor.contains(rtViewport)) {
if (!scissor.contains(rtWidth, rtHeight)) {
if (fHWScissorSettings.fRect != scissor) {
scissor.pushToGLScissor(this->glInterface());
fHWScissorSettings.fRect = scissor;
@ -1972,7 +1969,7 @@ void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
SkASSERT(windowState.numWindows() <= this->caps()->maxWindowRectangles());
if (!this->caps()->maxWindowRectangles() ||
fHWWindowRectsState.knownEqualTo(origin, rt->getViewport(), windowState)) {
fHWWindowRectsState.knownEqualTo(origin, rt->width(), rt->height(), windowState)) {
return;
}
@ -1984,13 +1981,13 @@ void GrGLGpu::flushWindowRectangles(const GrWindowRectsState& windowState,
GrGLIRect glwindows[GrWindowRectangles::kMaxWindows];
const SkIRect* skwindows = windowState.windows().data();
for (int i = 0; i < numWindows; ++i) {
glwindows[i].setRelativeTo(rt->getViewport(), skwindows[i], origin);
glwindows[i].setRelativeTo(rt->height(), skwindows[i], origin);
}
GrGLenum glmode = (Mode::kExclusive == windowState.mode()) ? GR_GL_EXCLUSIVE : GR_GL_INCLUSIVE;
GL_CALL(WindowRectangles(glmode, numWindows, glwindows->asInts()));
fHWWindowRectsState.set(origin, rt->getViewport(), windowState);
fHWWindowRectsState.set(origin, rt->width(), rt->height(), windowState);
#endif
}
@ -2098,7 +2095,7 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget,
if (pipeline.isScissorEnabled()) {
static constexpr SkIRect kBogusScissor{0, 0, 1, 1};
GrScissorState state(fixedDynamicState ? fixedDynamicState->fScissorRect : kBogusScissor);
this->flushScissor(state, glRT->getViewport(), origin);
this->flushScissor(state, glRT->width(), glRT->height(), origin);
} else {
this->disableScissor();
}
@ -2237,7 +2234,7 @@ void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color,
} else {
this->flushRenderTarget(glRT);
}
this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin);
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
this->flushColorWrite(true);
@ -2312,7 +2309,7 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTargetNoColorWrites(glRT);
this->flushScissor(clip.scissorState(), glRT->getViewport(), origin);
this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin);
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
GL_CALL(StencilMask((uint32_t) clipStencilMask));
@ -2365,8 +2362,7 @@ bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConf
if (!temp) {
return false;
}
GrGLIRect vp;
this->bindSurfaceFBOForPixelOps(temp.get(), GR_GL_FRAMEBUFFER, &vp, kDst_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(temp.get(), GR_GL_FRAMEBUFFER, kDst_TempFBOTarget);
fHWBoundRenderTargetUniqueID.makeInvalid();
return true;
}
@ -2415,7 +2411,6 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in
return false;
}
GrGLIRect glvp;
if (renderTarget) {
// resolve the render target if necessary
switch (renderTarget->getResolveType()) {
@ -2432,16 +2427,15 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in
default:
SK_ABORT("Unknown resolve type");
}
glvp = renderTarget->getViewport();
} else {
// Use a temporary FBO.
this->bindSurfaceFBOForPixelOps(surface, GR_GL_FRAMEBUFFER, &glvp, kSrc_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(surface, GR_GL_FRAMEBUFFER, kSrc_TempFBOTarget);
fHWBoundRenderTargetUniqueID.makeInvalid();
}
// the read rect is viewport-relative
GrGLIRect readRect;
readRect.setRelativeTo(glvp, left, top, width, height, kTopLeft_GrSurfaceOrigin);
readRect.setRelativeTo(surface->height(), left, top, width, height, kTopLeft_GrSurfaceOrigin);
// determine if GL can read using the passed rowBytes or if we need a scratch buffer.
if (rowWidthInPixels != width) {
@ -2572,7 +2566,7 @@ void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target) {
}
#endif
fHWBoundRenderTargetUniqueID = rtID;
this->flushViewport(target->getViewport());
this->flushViewport(target->width(), target->height());
}
if (this->glCaps().srgbWriteControl()) {
@ -2590,7 +2584,8 @@ void GrGLGpu::flushFramebufferSRGB(bool enable) {
}
}
void GrGLGpu::flushViewport(const GrGLIRect& viewport) {
void GrGLGpu::flushViewport(int width, int height) {
GrGLIRect viewport = {0, 0, width, height};
if (fHWViewport != viewport) {
viewport.pushToGLViewport(this->glInterface());
fHWViewport = viewport;
@ -2655,7 +2650,7 @@ void GrGLGpu::draw(GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
if (dynamicScissor) {
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
this->flushScissor(GrScissorState(dynamicStateArrays->fScissorRects[m]),
glRT->getViewport(), origin);
glRT->width(), glRT->height(), origin);
}
if (dynamicPrimProcTextures) {
auto texProxyArray = dynamicStateArrays->fPrimitiveProcessorTextures +
@ -2791,7 +2786,6 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
// make sure we go through flushRenderTarget() since we've modified
// the bound DRAW FBO ID.
fHWBoundRenderTargetUniqueID.makeInvalid();
const GrGLIRect& vp = rt->getViewport();
const SkIRect dirtyRect = rt->getResolveRect();
// The dirty rect tracked on the RT is always stored in the native coordinates of the
// surface. Choose kTopLeft so no adjustments are made
@ -2800,7 +2794,7 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
// Apple's extension uses the scissor as the blit bounds.
GrScissorState scissorState;
scissorState.set(dirtyRect);
this->flushScissor(scissorState, vp, kDirtyRectOrigin);
this->flushScissor(scissorState, rt->width(), rt->height(), kDirtyRectOrigin);
this->disableWindowRectangles();
GL_CALL(ResolveMultisampleFramebuffer());
} else {
@ -2813,7 +2807,7 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
t = target->height();
} else {
GrGLIRect rect;
rect.setRelativeTo(vp, dirtyRect, kDirtyRectOrigin);
rect.setRelativeTo(rt->height(), dirtyRect, kDirtyRectOrigin);
l = rect.fLeft;
b = rect.fBottom;
r = rect.fLeft + rect.fWidth;
@ -3272,9 +3266,8 @@ static inline bool can_copy_texsubimage(const GrSurface* dst, GrSurfaceOrigin ds
srcOrigin);
}
// If a temporary FBO was created, its non-zero ID is returned. The viewport that the copy rect is
// relative to is output.
void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
// If a temporary FBO was created, its non-zero ID is returned.
void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget,
TempFBOTarget tempFBOTarget) {
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(surface->asRenderTarget());
if (!rt) {
@ -3296,13 +3289,8 @@ void GrGLGpu::bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget,
texID,
0));
texture->baseLevelWasBoundToFBO();
viewport->fLeft = 0;
viewport->fBottom = 0;
viewport->fWidth = surface->width();
viewport->fHeight = surface->height();
} else {
this->bindFramebuffer(fboTarget, rt->renderFBOID());
*viewport = rt->getViewport();
}
}
@ -3698,9 +3686,8 @@ bool GrGLGpu::copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
this->bindTexture(0, GrSamplerState::ClampNearest(), srcTex);
GrGLIRect dstVP;
this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
this->flushViewport(dstVP);
this->bindSurfaceFBOForPixelOps(dst, GR_GL_FRAMEBUFFER, kDst_TempFBOTarget);
this->flushViewport(dst->width(), dst->height());
fHWBoundRenderTargetUniqueID.makeInvalid();
SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, dstPoint.fY, w, h);
@ -3773,14 +3760,13 @@ void GrGLGpu::copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOr
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
SkASSERT(can_copy_texsubimage(dst, dstOrigin, src, srcOrigin, this->glCaps()));
GrGLIRect srcVP;
this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(src, GR_GL_FRAMEBUFFER, kSrc_TempFBOTarget);
GrGLTexture* dstTex = static_cast<GrGLTexture *>(dst->asTexture());
SkASSERT(dstTex);
// We modified the bound FBO
fHWBoundRenderTargetUniqueID.makeInvalid();
GrGLIRect srcGLRect;
srcGLRect.setRelativeTo(srcVP, srcRect, srcOrigin);
srcGLRect.setRelativeTo(src->height(), srcRect, srcOrigin);
this->bindTextureToScratchUnit(dstTex->target(), dstTex->textureID());
GrGLint dstY;
@ -3813,16 +3799,14 @@ bool GrGLGpu::copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOr
}
}
GrGLIRect dstVP;
GrGLIRect srcVP;
this->bindSurfaceFBOForPixelOps(dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, &srcVP, kSrc_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(dst, GR_GL_DRAW_FRAMEBUFFER, kDst_TempFBOTarget);
this->bindSurfaceFBOForPixelOps(src, GR_GL_READ_FRAMEBUFFER, kSrc_TempFBOTarget);
// We modified the bound FBO
fHWBoundRenderTargetUniqueID.makeInvalid();
GrGLIRect srcGLRect;
GrGLIRect dstGLRect;
srcGLRect.setRelativeTo(srcVP, srcRect, srcOrigin);
dstGLRect.setRelativeTo(dstVP, dstRect, dstOrigin);
srcGLRect.setRelativeTo(src->height(), srcRect, srcOrigin);
dstGLRect.setRelativeTo(dst->height(), dstRect, dstOrigin);
// BlitFrameBuffer respects the scissor, so disable it.
this->disableScissor();
@ -3925,9 +3909,6 @@ bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) {
// Do all the blits:
width = texture->width();
height = texture->height();
GrGLIRect viewport;
viewport.fLeft = 0;
viewport.fBottom = 0;
for (GrGLint level = 1; level < levelCount; ++level) {
// Get and bind the program for this particular downsample (filter shape can vary):
@ -3957,9 +3938,7 @@ bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) {
width = SkTMax(1, width / 2);
height = SkTMax(1, height / 2);
viewport.fWidth = width;
viewport.fHeight = height;
this->flushViewport(viewport);
this->flushViewport(width, height);
GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
}

View File

@ -355,9 +355,7 @@ private:
// flushes the scissor. see the note on flushBoundTextureAndParams about
// flushing the scissor after that function is called.
void flushScissor(const GrScissorState&,
const GrGLIRect& rtViewport,
GrSurfaceOrigin rtOrigin);
void flushScissor(const GrScissorState&, int rtWidth, int rtHeight, GrSurfaceOrigin rtOrigin);
// disables the scissor
void disableScissor();
@ -382,7 +380,7 @@ private:
void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
// Need not be called if flushRenderTarget is used.
void flushViewport(const GrGLIRect&);
void flushViewport(int width, int height);
void flushStencil(const GrStencilSettings&, GrSurfaceOrigin);
void disableStencil();
@ -420,7 +418,7 @@ private:
// Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
// FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
// is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget,
TempFBOTarget tempFBOTarget);
// Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
@ -477,19 +475,21 @@ private:
fWindowState.setDisabled();
}
void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
void set(GrSurfaceOrigin rtOrigin, int width, int height,
const GrWindowRectsState& windowState) {
fRTOrigin = rtOrigin;
fViewport = viewport;
fWidth = width;
fHeight = height;
fWindowState = windowState;
}
bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height,
const GrWindowRectsState& windowState) const {
if (!this->valid()) {
return false;
}
if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
if (fWindowState.numWindows() &&
(fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) {
return false;
}
return fWindowState == windowState;
@ -499,7 +499,8 @@ private:
enum { kInvalidSurfaceOrigin = -1 };
int fRTOrigin;
GrGLIRect fViewport;
int fWidth;
int fHeight;
GrWindowRectsState fWindowState;
} fHWWindowRectsState;

View File

@ -53,23 +53,26 @@ struct GrGLIRect {
// sometimes we have a SkIRect from the client that we
// want to simultaneously make relative to GL's viewport
// and (optionally) convert from top-down to bottom-up.
void setRelativeTo(const GrGLIRect& glViewport, const SkIRect& devRect, GrSurfaceOrigin org) {
this->setRelativeTo(glViewport, devRect.x(), devRect.y(), devRect.width(), devRect.height(),
// The GL's viewport will always be the full size of the
// current render target so we just pass in the rtHeight
// here.
void setRelativeTo(int rtHeight, const SkIRect& devRect, GrSurfaceOrigin org) {
this->setRelativeTo(rtHeight, devRect.x(), devRect.y(), devRect.width(), devRect.height(),
org);
}
void setRelativeTo(const GrGLIRect& glRect,
void setRelativeTo(int fullHeight,
int leftOffset,
int topOffset,
int width,
int height,
GrSurfaceOrigin origin) {
fLeft = glRect.fLeft + leftOffset;
fLeft = leftOffset;
fWidth = width;
if (kBottomLeft_GrSurfaceOrigin == origin) {
fBottom = glRect.fBottom + (glRect.fHeight - topOffset - height);
fBottom = fullHeight - topOffset - height;
} else {
fBottom = glRect.fBottom + topOffset;
fBottom = topOffset;
}
fHeight = height;
@ -77,11 +80,11 @@ struct GrGLIRect {
SkASSERT(fHeight >= 0);
}
bool contains(const GrGLIRect& glRect) const {
return fLeft <= glRect.fLeft &&
fBottom <= glRect.fBottom &&
fLeft + fWidth >= glRect.fLeft + glRect.fWidth &&
fBottom + fHeight >= glRect.fBottom + glRect.fHeight;
bool contains(int width, int height) const {
return fLeft <= 0 &&
fBottom <= 0 &&
fLeft + fWidth >= width &&
fBottom + fHeight >= height;
}
void invalidate() {fLeft = fWidth = fBottom = fHeight = -1;}

View File

@ -91,7 +91,7 @@ void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fProxy->peekRenderTarget());
SkISize size = SkISize::Make(rt->width(), rt->height());
this->setProjectionMatrix(*args.fViewMatrix, size, args.fProxy->origin());
gpu->flushScissor(*args.fScissor, rt->getViewport(), args.fProxy->origin());
gpu->flushScissor(*args.fScissor, rt->width(), rt->height(), args.fProxy->origin());
gpu->flushHWAAState(rt, args.fUseHWAA);
gpu->flushRenderTarget(rt);

View File

@ -57,11 +57,6 @@ void GrGLRenderTarget::init(const GrSurfaceDesc& desc, GrGLenum format, const ID
fRTFormat = format;
fViewport.fLeft = 0;
fViewport.fBottom = 0;
fViewport.fWidth = desc.fWidth;
fViewport.fHeight = desc.fHeight;
fNumSamplesOwnedPerPixel = this->totalSamples();
}

View File

@ -40,9 +40,6 @@ public:
const IDDesc&,
int stencilBits);
void setViewport(const GrGLIRect& rect) { fViewport = rect; }
const GrGLIRect& getViewport() const { return fViewport; }
// The following two functions return the same ID when a texture/render target is not
// multisampled, and different IDs when it is multisampled.
// FBO ID used to render into
@ -106,11 +103,6 @@ private:
GrBackendObjectOwnership fRTFBOOwnership;
// when we switch to this render target we want to set the viewport to
// only render to content area (as opposed to the whole allocation) and
// we want the rendering to be at top left (GL has origin in bottom left)
GrGLIRect fViewport;
// The RenderTarget needs to be able to report its VRAM footprint even after abandon and
// release have potentially zeroed out the IDs (e.g., so the cache can reset itself). Since
// the IDs are just required for the computation in totalSamples we cache that result here.