aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2018-03-09 09:01:53 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-09 16:32:10 +0000
commitf865b05fe50ca2c094b9c60e4405c6094415b4f6 (patch)
treea00eab7c3787b5b977b3ae7c15aa1732f5a42c97 /src/gpu/gl
parentad06544cc6ac4b403a24adda4ee36b9f35b3071f (diff)
Add GM configs that test rendering to a GL backend texture and render target
This also adds GrGpu::create/deleteTestingOnlyBackendRenderTarget. Implemented in GL only for now. Change-Id: I9e5fdc953c4a249959af89e08332f520cefe9d90 Reviewed-on: https://skia-review.googlesource.com/113305 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLGpu.cpp78
-rw-r--r--src/gpu/gl/GrGLGpu.h16
2 files changed, 86 insertions, 8 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 82be0d1a97..7499e761c9 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4344,6 +4344,7 @@ void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
}
}
+#if GR_TEST_UTILS
GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h,
GrPixelConfig config, bool /*isRT*/,
GrMipMapped mipMapped) {
@@ -4434,13 +4435,86 @@ void GrGLGpu::deleteTestingOnlyBackendTexture(GrBackendTexture* tex) {
}
}
-void GrGLGpu::resetShaderCacheForTesting() const {
- fProgramCache->abandon();
+GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h,
+ GrColorType colorType,
+ GrSRGBEncoded srgbEncoded) {
+ auto config = GrColorTypeToPixelConfig(colorType, srgbEncoded);
+ GrGLenum colorBufferFormat;
+ if (!this->glCaps().getRenderbufferFormat(config, &colorBufferFormat)) {
+ return {};
+ }
+ int sFormatIdx = this->getCompatibleStencilIndex(config);
+ if (sFormatIdx < 0) {
+ return {};
+ }
+ GrGLuint rbIDs[] = {0, 0};
+ GL_CALL(GenRenderbuffers(2, rbIDs));
+ if (!rbIDs[0] || !rbIDs[1]) {
+ if (!rbIDs[0]) {
+ GL_CALL(DeleteRenderbuffers(1, &rbIDs[0]));
+ }
+ if (!rbIDs[1]) {
+ GL_CALL(DeleteRenderbuffers(1, &rbIDs[1]));
+ }
+ return {};
+ }
+ GrGLFramebufferInfo info;
+ info.fFBOID = 0;
+ GL_CALL(GenFramebuffers(1, &info.fFBOID));
+ if (!info.fFBOID) {
+ GL_CALL(DeleteRenderbuffers(2, rbIDs));
+ return GrBackendRenderTarget();
+ }
+
+ this->invalidateBoundRenderTarget();
+
+ GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID));
+ GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[0]));
+ GL_ALLOC_CALL(this->glInterface(),
+ RenderbufferStorage(GR_GL_RENDERBUFFER, colorBufferFormat, w, h));
+ GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_RENDERBUFFER,
+ rbIDs[0]));
+ GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, rbIDs[1]));
+ auto stencilBufferFormat = this->glCaps().stencilFormats()[sFormatIdx].fInternalFormat;
+ GL_ALLOC_CALL(this->glInterface(),
+ RenderbufferStorage(GR_GL_RENDERBUFFER, stencilBufferFormat, w, h));
+ GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, GR_GL_RENDERBUFFER,
+ rbIDs[1]));
+ if (this->glCaps().stencilFormats()[sFormatIdx].fPacked) {
+ GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_DEPTH_ATTACHMENT,
+ GR_GL_RENDERBUFFER, rbIDs[1]));
+ }
+
+ // We don't want to have to recover the renderbuffer IDs later to delete them. OpenGL has this
+ // rule that if a renderbuffer is deleted and a FBO other than the current FBO has the RB
+ // attached then deletion is delayed. So we unbind the FBO here and delete the renderbuffers.
+ GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
+ GL_CALL(DeleteRenderbuffers(2, rbIDs));
+
+ GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, info.fFBOID));
+ GrGLenum status;
+ GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
+ if (GR_GL_FRAMEBUFFER_COMPLETE != status) {
+ GL_CALL(DeleteFramebuffers(1, &info.fFBOID));
+ return {};
+ }
+ auto stencilBits = SkToInt(this->glCaps().stencilFormats()[sFormatIdx].fStencilBits);
+ return {w, h, 1, stencilBits, config, info};
+}
+
+void GrGLGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& backendRT) {
+ SkASSERT(kOpenGL_GrBackend == backendRT.backend());
+ if (auto info = backendRT.getGLFramebufferInfo()) {
+ if (info->fFBOID) {
+ GL_CALL(DeleteFramebuffers(1, &info->fFBOID));
+ }
+ }
}
void GrGLGpu::testingOnly_flushGpuAndSync() {
GL_CALL(Finish());
}
+#endif
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 3a67958d5f..fa3d9e09c7 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -128,10 +128,6 @@ public:
void clearStencilClip(const GrFixedClip&, bool insideStencilMask,
GrRenderTarget*, GrSurfaceOrigin);
- const GrGLContext* glContextForTesting() const override {
- return &this->glContext();
- }
-
void clearStencil(GrRenderTarget*, int clearValue) override;
GrGpuRTCommandBuffer* createCommandBuffer(
@@ -148,7 +144,7 @@ public:
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
int width,
int height) override;
-
+#if GR_TEST_UTILS
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h,
GrPixelConfig config,
bool isRenderTarget,
@@ -156,9 +152,17 @@ public:
bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
void deleteTestingOnlyBackendTexture(GrBackendTexture*) override;
- void resetShaderCacheForTesting() const override;
+ GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType,
+ GrSRGBEncoded) override;
+
+ void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
+
+ const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
+
+ void resetShaderCacheForTesting() const override { fProgramCache->abandon(); }
void testingOnly_flushGpuAndSync() override;
+#endif
GrFence SK_WARN_UNUSED_RESULT insertFence() override;
bool waitFence(GrFence, uint64_t timeout) override;