blob: 0c5209fa2604bb3259cea2db20e646ea1ed241dc [file] [log] [blame]
reeda1e41c62015-04-09 13:43:22 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
yangsu@google.com688823f2011-08-30 19:14:13 +00008#import "SkSampleUIView.h"
9
reeda1e41c62015-04-09 13:43:22 -070010//#define SKGL_CONFIG kEAGLColorFormatRGB565
11#define SKGL_CONFIG kEAGLColorFormatRGBA8
yangsu@google.com688823f2011-08-30 19:14:13 +000012
13#define FORCE_REDRAW
14
caryclark@google.com5987f582012-10-02 18:33:14 +000015#include "SkCanvas.h"
16#include "SkCGUtils.h"
reedf0b17102014-10-22 13:06:00 -070017#include "SkSurface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000018#include "SampleApp.h"
19
20#if SK_SUPPORT_GPU
yangsu@google.com688823f2011-08-30 19:14:13 +000021//#define USE_GL_1
22#define USE_GL_2
23
tomhudson@google.com02f90e82012-02-14 15:43:01 +000024#include "gl/GrGLInterface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000025#include "GrContext.h"
yangsu@google.com688823f2011-08-30 19:14:13 +000026#include "SkGpuDevice.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000027#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000028
yangsu@google.com688823f2011-08-30 19:14:13 +000029class SkiOSDeviceManager : public SampleWindow::DeviceManager {
30public:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000031 SkiOSDeviceManager(GLint layerFBO) {
bsalomon@google.com230504d2012-09-27 16:04:54 +000032#if SK_SUPPORT_GPU
33 fCurContext = NULL;
34 fCurIntf = NULL;
35 fCurRenderTarget = NULL;
36 fMSAASampleCount = 0;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000037 fLayerFBO = layerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +000038#endif
39 fBackend = SkOSWindow::kNone_BackEndType;
yangsu@google.com688823f2011-08-30 19:14:13 +000040 }
41
bsalomon@google.com230504d2012-09-27 16:04:54 +000042 virtual ~SkiOSDeviceManager() {
43#if SK_SUPPORT_GPU
44 SkSafeUnref(fCurContext);
45 SkSafeUnref(fCurIntf);
46 SkSafeUnref(fCurRenderTarget);
yangsu@google.com688823f2011-08-30 19:14:13 +000047#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000048 }
49
mtklein36352bf2015-03-25 18:17:31 -070050 void setUpBackend(SampleWindow* win, int msaaSampleCount) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +000051 SkASSERT(SkOSWindow::kNone_BackEndType == fBackend);
52
53 fBackend = SkOSWindow::kNone_BackEndType;
54
55#if SK_SUPPORT_GPU
56 switch (win->getDeviceType()) {
bsalomon@google.com230504d2012-09-27 16:04:54 +000057 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000058 break;
59 // these guys use the native backend
60 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000061 fBackend = SkOSWindow::kNativeGL_BackEndType;
62 break;
63 default:
64 SkASSERT(false);
65 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000066 }
bsalomon@google.com64cc8102013-03-05 20:06:05 +000067 SkOSWindow::AttachmentInfo info;
68 bool result = win->attach(fBackend, msaaSampleCount, &info);
bsalomon@google.com230504d2012-09-27 16:04:54 +000069 if (!result) {
70 SkDebugf("Failed to initialize GL");
71 return;
yangsu@google.com688823f2011-08-30 19:14:13 +000072 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000073 fMSAASampleCount = msaaSampleCount;
74
75 SkASSERT(NULL == fCurIntf);
76 switch (win->getDeviceType()) {
yangsu@google.com688823f2011-08-30 19:14:13 +000077 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000078 fCurIntf = NULL;
79 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000080 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000081 fCurIntf = GrGLCreateNativeInterface();
82 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000083 default:
bsalomon@google.com230504d2012-09-27 16:04:54 +000084 SkASSERT(false);
85 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000086 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000087
88 SkASSERT(NULL == fCurContext);
89 if (SkOSWindow::kNone_BackEndType != fBackend) {
bsalomon@google.com365d7872013-02-07 17:01:39 +000090 fCurContext = GrContext::Create(kOpenGL_GrBackend,
91 (GrBackendContext) fCurIntf);
bsalomon@google.com230504d2012-09-27 16:04:54 +000092 }
93
94 if ((NULL == fCurContext || NULL == fCurIntf) &&
95 SkOSWindow::kNone_BackEndType != fBackend) {
96 // We need some context and interface to see results if we're using a GL backend
97 SkSafeUnref(fCurContext);
98 SkSafeUnref(fCurIntf);
99 SkDebugf("Failed to setup 3D");
100 win->detach();
101 }
102#endif // SK_SUPPORT_GPU
103 // call windowSizeChanged to create the render target
104 this->windowSizeChanged(win);
yangsu@google.com688823f2011-08-30 19:14:13 +0000105 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000106
mtklein36352bf2015-03-25 18:17:31 -0700107 void tearDownBackend(SampleWindow *win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000108#if SK_SUPPORT_GPU
109 SkSafeUnref(fCurContext);
110 fCurContext = NULL;
111
112 SkSafeUnref(fCurIntf);
113 fCurIntf = NULL;
114
115 SkSafeUnref(fCurRenderTarget);
116 fCurRenderTarget = NULL;
117#endif
118 win->detach();
119 fBackend = SampleWindow::kNone_BackEndType;
120 }
reed@google.com5957f472012-10-01 20:31:56 +0000121
mtklein36352bf2015-03-25 18:17:31 -0700122 SkSurface* createSurface(SampleWindow::DeviceType dType, SampleWindow* win) override{
bsalomon@google.com230504d2012-09-27 16:04:54 +0000123#if SK_SUPPORT_GPU
reedf0b17102014-10-22 13:06:00 -0700124 if (SampleWindow::IsGpuDeviceType(dType) && fCurContext) {
125 SkSurfaceProps props(win->getSurfaceProps());
126 return SkSurface::NewRenderTargetDirect(fCurRenderTarget, &props);
yangsu@google.com688823f2011-08-30 19:14:13 +0000127 }
reedf0b17102014-10-22 13:06:00 -0700128#endif
reed@google.com5957f472012-10-01 20:31:56 +0000129 return NULL;
yangsu@google.com688823f2011-08-30 19:14:13 +0000130 }
reedf0b17102014-10-22 13:06:00 -0700131
yangsu@google.com688823f2011-08-30 19:14:13 +0000132 virtual void publishCanvas(SampleWindow::DeviceType dType,
133 SkCanvas* canvas,
mtklein36352bf2015-03-25 18:17:31 -0700134 SampleWindow* win) override {
caryclark@google.com5987f582012-10-02 18:33:14 +0000135#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000136 if (NULL != fCurContext) {
137 fCurContext->flush();
138 }
caryclark@google.com5987f582012-10-02 18:33:14 +0000139#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000140 win->present();
yangsu@google.com688823f2011-08-30 19:14:13 +0000141 }
142
mtklein36352bf2015-03-25 18:17:31 -0700143 void windowSizeChanged(SampleWindow* win) override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000144#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000145 if (NULL != fCurContext) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000146 SkOSWindow::AttachmentInfo info;
147
148 win->attach(fBackend, fMSAASampleCount, &info);
yangsu@google.com688823f2011-08-30 19:14:13 +0000149
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000150 glBindFramebuffer(GL_FRAMEBUFFER, fLayerFBO);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000151 GrBackendRenderTargetDesc desc;
reed@google.com26deb232013-12-17 19:50:57 +0000152 desc.fWidth = SkScalarRoundToInt(win->width());
153 desc.fHeight = SkScalarRoundToInt(win->height());
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000154 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000155 desc.fRenderTargetHandle = fLayerFBO;
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000156 desc.fSampleCnt = info.fSampleCount;
157 desc.fStencilBits = info.fStencilBits;
158
bsalomon@google.com230504d2012-09-27 16:04:54 +0000159 SkSafeUnref(fCurRenderTarget);
caryclarkb4fd8932015-08-21 08:08:07 -0700160 fCurRenderTarget = fCurContext->textureProvider()->wrapBackendRenderTarget(desc);
yangsu@google.com688823f2011-08-30 19:14:13 +0000161 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000162#endif
yangsu@google.com688823f2011-08-30 19:14:13 +0000163 }
164
mtklein36352bf2015-03-25 18:17:31 -0700165 GrContext* getGrContext() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000166#if SK_SUPPORT_GPU
167 return fCurContext;
168#else
169 return NULL;
170#endif
171 }
yangsu@google.com688823f2011-08-30 19:14:13 +0000172
mtklein36352bf2015-03-25 18:17:31 -0700173 GrRenderTarget* getGrRenderTarget() override {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000174#if SK_SUPPORT_GPU
175 return fCurRenderTarget;
176#else
177 return NULL;
178#endif
bsalomon@google.com11959252012-04-06 20:13:38 +0000179 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000180
181 bool isUsingGL() const { return SkOSWindow::kNone_BackEndType != fBackend; }
182
yangsu@google.com688823f2011-08-30 19:14:13 +0000183private:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000184
bsalomon@google.com230504d2012-09-27 16:04:54 +0000185#if SK_SUPPORT_GPU
186 GrContext* fCurContext;
187 const GrGLInterface* fCurIntf;
188 GrRenderTarget* fCurRenderTarget;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000189 int fMSAASampleCount;
190 GLint fLayerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000191#endif
192
193 SkOSWindow::SkBackEndTypes fBackend;
194
195 typedef SampleWindow::DeviceManager INHERITED;
yangsu@google.com688823f2011-08-30 19:14:13 +0000196};
197
198////////////////////////////////////////////////////////////////////////////////
199@implementation SkSampleUIView
200
201@synthesize fTitle, fRasterLayer, fGLLayer;
202
203#include "SkApplication.h"
204#include "SkEvent.h"
205#include "SkWindow.h"
206
yangsu@google.com688823f2011-08-30 19:14:13 +0000207struct FPSState {
208 static const int FRAME_COUNT = 60;
209
210 CFTimeInterval fNow0, fNow1;
211 CFTimeInterval fTime0, fTime1, fTotalTime;
212 int fFrameCounter;
yangsu@google.com688823f2011-08-30 19:14:13 +0000213 SkString str;
214 FPSState() {
215 fTime0 = fTime1 = fTotalTime = 0;
216 fFrameCounter = 0;
217 }
218
219 void startDraw() {
220 fNow0 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000221 }
222
223 void endDraw() {
224 fNow1 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000225 }
226
227 void flush(SkOSWindow* hwnd) {
228 CFTimeInterval now2 = CACurrentMediaTime();
229
230 fTime0 += fNow1 - fNow0;
231 fTime1 += now2 - fNow1;
232
233 if (++fFrameCounter == FRAME_COUNT) {
234 CFTimeInterval totalNow = CACurrentMediaTime();
235 fTotalTime = totalNow - fTotalTime;
236
237 //SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
238 //SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
239 //str.printf(" ms: %d [%d], fps: %3.1f", msTotal, ms0,
240 // FRAME_COUNT / fTotalTime);
241 str.printf(" fps:%3.1f", FRAME_COUNT / fTotalTime);
242 hwnd->setTitle(NULL);
243 fTotalTime = totalNow;
244 fTime0 = fTime1 = 0;
245 fFrameCounter = 0;
246 }
247 }
248};
249
250static FPSState gFPS;
251
252#define FPS_StartDraw() gFPS.startDraw()
253#define FPS_EndDraw() gFPS.endDraw()
254#define FPS_Flush(wind) gFPS.flush(wind)
255
256///////////////////////////////////////////////////////////////////////////////
257
258- (id)initWithDefaults {
259 if (self = [super initWithDefaults]) {
260 fRedrawRequestPending = false;
261 fFPSState = new FPSState;
262
263#ifdef USE_GL_1
264 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
265#else
266 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
267#endif
268
269 if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
270 {
271 [self release];
272 return nil;
273 }
274
275 // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
276 glGenFramebuffers(1, &fGL.fFramebuffer);
277 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
278
279 glGenRenderbuffers(1, &fGL.fRenderbuffer);
280 glGenRenderbuffers(1, &fGL.fStencilbuffer);
281
282 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
283 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fGL.fRenderbuffer);
284
285 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
286 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fGL.fStencilbuffer);
287
288 self.fGLLayer = [CAEAGLLayer layer];
289 fGLLayer.bounds = self.bounds;
290 fGLLayer.anchorPoint = CGPointMake(0, 0);
291 fGLLayer.opaque = TRUE;
292 [self.layer addSublayer:fGLLayer];
293 fGLLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
294 [NSNumber numberWithBool:NO],
295 kEAGLDrawablePropertyRetainedBacking,
296 SKGL_CONFIG,
297 kEAGLDrawablePropertyColorFormat,
298 nil];
299
300 self.fRasterLayer = [CALayer layer];
301 fRasterLayer.anchorPoint = CGPointMake(0, 0);
302 fRasterLayer.opaque = TRUE;
303 [self.layer addSublayer:fRasterLayer];
304
caryclark@google.com5987f582012-10-02 18:33:14 +0000305 NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
yangsu@google.com688823f2011-08-30 19:14:13 +0000306 [NSNull null], @"onOrderOut",
307 [NSNull null], @"sublayers",
308 [NSNull null], @"contents",
309 [NSNull null], @"bounds",
310 nil];
311 fGLLayer.actions = newActions;
312 fRasterLayer.actions = newActions;
313 [newActions release];
314
jvanverth44dcb8a2015-10-02 09:12:05 -0700315 // rebuild argc and argv from process info
316 NSArray* arguments = [[NSProcessInfo processInfo] arguments];
317 int argc = [arguments count];
318 char** argv = new char*[argc];
319 for (int i = 0; i < argc; ++i) {
320 NSString* arg = [arguments objectAtIndex:i];
321 int strlen = [arg lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
322 argv[i] = new char[strlen+1];
323 [arg getCString:argv[i] maxLength:strlen+1 encoding:NSUTF8StringEncoding];
324 }
325
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000326 fDevManager = new SkiOSDeviceManager(fGL.fFramebuffer);
jvanverth44dcb8a2015-10-02 09:12:05 -0700327 fWind = new SampleWindow(self, argc, argv, fDevManager);
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000328
kkinnunen973d92c2016-01-18 01:18:34 -0800329 fWind->resize(self.frame.size.width, self.frame.size.height);
jvanverth44dcb8a2015-10-02 09:12:05 -0700330
331 for (int i = 0; i < argc; ++i) {
332 delete [] argv[i];
333 }
334 delete [] argv;
yangsu@google.com688823f2011-08-30 19:14:13 +0000335 }
336 return self;
337}
338
339- (void)dealloc {
340 delete fDevManager;
341 delete fFPSState;
342 self.fRasterLayer = nil;
343 self.fGLLayer = nil;
344 [fGL.fContext release];
345 [super dealloc];
346}
347
348- (void)layoutSubviews {
349 int W, H;
350
351 // Allocate color buffer backing based on the current layer size
352 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
353 [fGL.fContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:fGLLayer];
354
355 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &fGL.fWidth);
356 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &fGL.fHeight);
357
358 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
359 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fGL.fWidth, fGL.fHeight);
360
361 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
362 NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
363 }
364
365 if (fDevManager->isUsingGL()) {
366 W = fGL.fWidth;
367 H = fGL.fHeight;
368 CGRect rect = CGRectMake(0, 0, W, H);
369 fGLLayer.bounds = rect;
370 }
371 else {
372 CGRect rect = self.bounds;
373 W = (int)CGRectGetWidth(rect);
374 H = (int)CGRectGetHeight(rect);
375 fRasterLayer.bounds = rect;
376 }
377
378 printf("---- layoutSubviews %d %d\n", W, H);
379 fWind->resize(W, H);
380 fWind->inval(NULL);
381}
382
383///////////////////////////////////////////////////////////////////////////////
384
385- (void)drawWithCanvas:(SkCanvas*)canvas {
386 fRedrawRequestPending = false;
387 fFPSState->startDraw();
388 fWind->draw(canvas);
389 fFPSState->endDraw();
390#ifdef FORCE_REDRAW
391 fWind->inval(NULL);
392#endif
393 fFPSState->flush(fWind);
394}
395
396- (void)drawInGL {
397 // This application only creates a single context which is already set current at this point.
398 // This call is redundant, but needed if dealing with multiple contexts.
399 [EAGLContext setCurrentContext:fGL.fContext];
400
401 // This application only creates a single default framebuffer which is already bound at this point.
402 // This call is redundant, but needed if dealing with multiple framebuffers.
403 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
404
405 GLint scissorEnable;
406 glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
407 glDisable(GL_SCISSOR_TEST);
408 glClearColor(0,0,0,0);
409 glClear(GL_COLOR_BUFFER_BIT);
410 if (scissorEnable) {
411 glEnable(GL_SCISSOR_TEST);
412 }
413 glViewport(0, 0, fGL.fWidth, fGL.fHeight);
414
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000415
reedf0b17102014-10-22 13:06:00 -0700416 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
417 SkCanvas* canvas = surface->getCanvas();
418
yangsu@google.com688823f2011-08-30 19:14:13 +0000419 // if we're not "retained", then we have to always redraw everything.
420 // This call forces us to ignore the fDirtyRgn, and draw everywhere.
421 // If we are "retained", we can skip this call (as the raster case does)
422 fWind->forceInvalAll();
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000423
reed@google.com5957f472012-10-01 20:31:56 +0000424 [self drawWithCanvas:canvas];
reedf0b17102014-10-22 13:06:00 -0700425
yangsu@google.com688823f2011-08-30 19:14:13 +0000426 // This application only creates a single color renderbuffer which is already bound at this point.
427 // This call is redundant, but needed if dealing with multiple renderbuffers.
428 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
429 [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER];
yangsu@google.com688823f2011-08-30 19:14:13 +0000430}
431
432- (void)drawInRaster {
reedf0b17102014-10-22 13:06:00 -0700433 SkAutoTUnref<SkSurface> surface(fWind->createSurface());
434 SkCanvas* canvas = surface->getCanvas();
reed@google.com5957f472012-10-01 20:31:56 +0000435 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000436 CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
437 fRasterLayer.contents = (id)cgimage;
438 CGImageRelease(cgimage);
439}
440
441- (void)forceRedraw {
442 if (fDevManager->isUsingGL())
443 [self drawInGL];
444 else
445 [self drawInRaster];
446}
447
448///////////////////////////////////////////////////////////////////////////////
449
450- (void)setSkTitle:(const char *)title {
451 NSString* text = [NSString stringWithUTF8String:title];
452 if ([text length] > 0)
453 self.fTitle = text;
454
455 if (fTitleItem && fTitle) {
456 fTitleItem.title = [NSString stringWithFormat:@"%@%@", fTitle,
457 [NSString stringWithUTF8String:fFPSState->str.c_str()]];
458 }
459}
460
461- (void)postInvalWithRect:(const SkIRect*)r {
462 if (!fRedrawRequestPending) {
463 fRedrawRequestPending = true;
464 bool gl = fDevManager->isUsingGL();
465 [CATransaction begin];
466 [CATransaction setAnimationDuration:0];
467 fRasterLayer.hidden = gl;
468 fGLLayer.hidden = !gl;
469 [CATransaction commit];
470 if (gl) {
471 [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
472 }
473 else {
474 [self performSelector:@selector(drawInRaster) withObject:nil afterDelay:0];
475 [self setNeedsDisplay];
476 }
477 }
478}
479
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000480- (void)getAttachmentInfo:(SkOSWindow::AttachmentInfo*)info {
481 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
482 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
483 GL_RENDERBUFFER_STENCIL_SIZE,
484 &info->fStencilBits);
485 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
486 GL_RENDERBUFFER_SAMPLES_APPLE,
487 &info->fSampleCount);
488}
489
yangsu@google.com688823f2011-08-30 19:14:13 +0000490@end