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 14 SkGLWidget::SkGLWidget(SkDebugger* debugger) : QGLWidget() { 15 fDebugger = debugger; 16 } 17 18 SkGLWidget::~SkGLWidget() { 19 } 20 21 void SkGLWidget::setSampleCount(int sampleCount) { 22 QGLFormat currentFormat = format(); 23 currentFormat.setSampleBuffers(sampleCount > 0); 24 currentFormat.setSamples(sampleCount); 25 setFormat(currentFormat); 26 } 27 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 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 71 void SkGLWidget::resizeGL(int w, int h) { 72 SkASSERT(w == this->width() && h == this->height()); 73 this->createRenderTarget(); 74 } 75 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 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