1 
2 /*
3  * Copyright 2012 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #include "SkGLWidget.h"
11 
12 #if SK_SUPPORT_GPU
13 
SkGLWidget(SkDebugger * debugger)14 SkGLWidget::SkGLWidget(SkDebugger* debugger) : QGLWidget() {
15     fDebugger = debugger;
16 }
17 
~SkGLWidget()18 SkGLWidget::~SkGLWidget() {
19 }
20 
setSampleCount(int sampleCount)21 void SkGLWidget::setSampleCount(int sampleCount) {
22     QGLFormat currentFormat = format();
23     currentFormat.setSampleBuffers(sampleCount > 0);
24     currentFormat.setSamples(sampleCount);
25     setFormat(currentFormat);
26 }
27 
initializeGL()28 void SkGLWidget::initializeGL() {
29     if (!fCurIntf) {
30         fCurIntf.reset(GrGLCreateNativeInterface());
31     }
32     if (!fCurIntf) {
33         return;
34     }
35     // The call may come multiple times, for example after setSampleCount().  The QGLContext will be
36     // different, but we do not have a mechanism to catch the destroying of QGLContext, so that
37     // proper resource cleanup could be made.
38     if (fCurContext) {
39         fCurContext->abandonContext();
40     }
41     fGpuDevice.reset(nullptr);
42     fCanvas.reset(nullptr);
43 
44     fCurContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf.get()));
45 }
46 
createRenderTarget()47 void SkGLWidget::createRenderTarget() {
48     if (!fCurContext) {
49         return;
50     }
51 
52     glDisable(GL_SCISSOR_TEST);
53     glStencilMask(0xffffffff);
54     glClearStencil(0);
55     glClear(GL_STENCIL_BUFFER_BIT);
56     fCurContext->resetContext();
57 
58     fGpuDevice.reset(nullptr);
59     fCanvas.reset(nullptr);
60 
61     GrBackendRenderTargetDesc desc = this->getDesc(this->width(), this->height());
62     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
63     SkAutoTUnref<GrRenderTarget> curRenderTarget(
64             fCurContext->textureProvider()->wrapBackendRenderTarget(desc));
65     SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
66     fGpuDevice.reset(SkGpuDevice::Create(curRenderTarget, &props,
67                                          SkGpuDevice::kUninit_InitContents));
68     fCanvas.reset(new SkCanvas(fGpuDevice));
69 }
70 
resizeGL(int w,int h)71 void SkGLWidget::resizeGL(int w, int h) {
72     SkASSERT(w == this->width() && h == this->height());
73     this->createRenderTarget();
74 }
75 
paintGL()76 void SkGLWidget::paintGL() {
77     if (!this->isHidden() && fCanvas) {
78         fCurContext->resetContext();
79         fDebugger->draw(fCanvas.get());
80         // TODO(chudy): Implement an optional flush button in Gui.
81         fCanvas->flush();
82         emit drawComplete();
83     }
84 }
85 
getDesc(int w,int h)86 GrBackendRenderTargetDesc SkGLWidget::getDesc(int w, int h) {
87     GrBackendRenderTargetDesc desc;
88     desc.fWidth = SkScalarRoundToInt(this->width());
89     desc.fHeight = SkScalarRoundToInt(this->height());
90     desc.fConfig = kSkia8888_GrPixelConfig;
91     GR_GL_GetIntegerv(fCurIntf, GR_GL_SAMPLES, &desc.fSampleCnt);
92     GR_GL_GetIntegerv(fCurIntf, GR_GL_STENCIL_BITS, &desc.fStencilBits);
93     GrGLint buffer;
94     GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
95     desc.fRenderTargetHandle = buffer;
96 
97     return desc;
98 }
99 
100 #endif
101