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(NULL); 42 fCanvas.reset(NULL); 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(NULL); 59 fCanvas.reset(NULL); 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(SkSurfaceProps::kLegacyFontHost_InitType); 66 fGpuDevice.reset(SkGpuDevice::Create(curRenderTarget, &props)); 67 fCanvas.reset(new SkCanvas(fGpuDevice)); 68 } 69 70 void SkGLWidget::resizeGL(int w, int h) { 71 SkASSERT(w == this->width() && h == this->height()); 72 this->createRenderTarget(); 73 } 74 75 void SkGLWidget::paintGL() { 76 if (!this->isHidden() && fCanvas) { 77 fCurContext->resetContext(); 78 fDebugger->draw(fCanvas.get()); 79 // TODO(chudy): Implement an optional flush button in Gui. 80 fCanvas->flush(); 81 emit drawComplete(); 82 } 83 } 84 85 GrBackendRenderTargetDesc SkGLWidget::getDesc(int w, int h) { 86 GrBackendRenderTargetDesc desc; 87 desc.fWidth = SkScalarRoundToInt(this->width()); 88 desc.fHeight = SkScalarRoundToInt(this->height()); 89 desc.fConfig = kSkia8888_GrPixelConfig; 90 GR_GL_GetIntegerv(fCurIntf, GR_GL_SAMPLES, &desc.fSampleCnt); 91 GR_GL_GetIntegerv(fCurIntf, GR_GL_STENCIL_BITS, &desc.fStencilBits); 92 GrGLint buffer; 93 GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer); 94 desc.fRenderTargetHandle = buffer; 95 96 return desc; 97 } 98 99 #endif 100