blob: a9defbe610f6bb24b8da9851189702821300fc82 [file] [log] [blame]
yangsu@google.com688823f2011-08-30 19:14:13 +00001#import "SkSampleUIView.h"
2
yangsu@google.com688823f2011-08-30 19:14:13 +00003#define SKGL_CONFIG kEAGLColorFormatRGB565
4//#define SKGL_CONFIG kEAGLColorFormatRGBA8
5
6#define FORCE_REDRAW
7
caryclark@google.com5987f582012-10-02 18:33:14 +00008#include "SkCanvas.h"
9#include "SkCGUtils.h"
10#include "SampleApp.h"
11
12#if SK_SUPPORT_GPU
yangsu@google.com688823f2011-08-30 19:14:13 +000013//#define USE_GL_1
14#define USE_GL_2
15
tomhudson@google.com02f90e82012-02-14 15:43:01 +000016#include "gl/GrGLInterface.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000017#include "GrContext.h"
yangsu@google.com688823f2011-08-30 19:14:13 +000018#include "SkGpuDevice.h"
caryclark@google.com5987f582012-10-02 18:33:14 +000019#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000020
yangsu@google.com688823f2011-08-30 19:14:13 +000021class SkiOSDeviceManager : public SampleWindow::DeviceManager {
22public:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000023 SkiOSDeviceManager(GLint layerFBO) {
bsalomon@google.com230504d2012-09-27 16:04:54 +000024#if SK_SUPPORT_GPU
25 fCurContext = NULL;
26 fCurIntf = NULL;
27 fCurRenderTarget = NULL;
28 fMSAASampleCount = 0;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +000029 fLayerFBO = layerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +000030#endif
31 fBackend = SkOSWindow::kNone_BackEndType;
yangsu@google.com688823f2011-08-30 19:14:13 +000032 }
33
bsalomon@google.com230504d2012-09-27 16:04:54 +000034 virtual ~SkiOSDeviceManager() {
35#if SK_SUPPORT_GPU
36 SkSafeUnref(fCurContext);
37 SkSafeUnref(fCurIntf);
38 SkSafeUnref(fCurRenderTarget);
yangsu@google.com688823f2011-08-30 19:14:13 +000039#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +000040 }
41
42 virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) SK_OVERRIDE {
43 SkASSERT(SkOSWindow::kNone_BackEndType == fBackend);
44
45 fBackend = SkOSWindow::kNone_BackEndType;
46
47#if SK_SUPPORT_GPU
48 switch (win->getDeviceType()) {
49 // these two don't use GL
50 case SampleWindow::kRaster_DeviceType:
51 case SampleWindow::kPicture_DeviceType:
52 break;
53 // these guys use the native backend
54 case SampleWindow::kGPU_DeviceType:
55 case SampleWindow::kNullGPU_DeviceType:
56 fBackend = SkOSWindow::kNativeGL_BackEndType;
57 break;
58 default:
59 SkASSERT(false);
60 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000061 }
bsalomon@google.com64cc8102013-03-05 20:06:05 +000062 SkOSWindow::AttachmentInfo info;
63 bool result = win->attach(fBackend, msaaSampleCount, &info);
bsalomon@google.com230504d2012-09-27 16:04:54 +000064 if (!result) {
65 SkDebugf("Failed to initialize GL");
66 return;
yangsu@google.com688823f2011-08-30 19:14:13 +000067 }
bsalomon@google.com230504d2012-09-27 16:04:54 +000068 fMSAASampleCount = msaaSampleCount;
69
70 SkASSERT(NULL == fCurIntf);
71 switch (win->getDeviceType()) {
72 // these two don't use GL
yangsu@google.com688823f2011-08-30 19:14:13 +000073 case SampleWindow::kRaster_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000074 case SampleWindow::kPicture_DeviceType:
75 fCurIntf = NULL;
76 break;
yangsu@google.com688823f2011-08-30 19:14:13 +000077 case SampleWindow::kGPU_DeviceType:
bsalomon@google.com230504d2012-09-27 16:04:54 +000078 fCurIntf = GrGLCreateNativeInterface();
79 break;
80 case SampleWindow::kNullGPU_DeviceType:
81 fCurIntf = GrGLCreateNullInterface();
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
107 virtual void tearDownBackend(SampleWindow *win) SK_OVERRIDE {
108#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
122 virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
123 SampleWindow* win) {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000124 switch (dType) {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000125 case SampleWindow::kRaster_DeviceType:
reed@google.com5957f472012-10-01 20:31:56 +0000126 // fallthrough
bsalomon@google.com230504d2012-09-27 16:04:54 +0000127 case SampleWindow::kPicture_DeviceType:
reed@google.com5957f472012-10-01 20:31:56 +0000128 // fallthrough
129#if SK_ANGLE
130 case SampleWindow::kANGLE_DeviceType:
131#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000132 break;
133#if SK_SUPPORT_GPU
bsalomon@google.com230504d2012-09-27 16:04:54 +0000134 case SampleWindow::kGPU_DeviceType:
135 case SampleWindow::kNullGPU_DeviceType:
reed@google.com5957f472012-10-01 20:31:56 +0000136 if (fCurContext) {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000137 SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(fCurContext,
138 fCurRenderTarget));
reed@google.com5957f472012-10-01 20:31:56 +0000139 return new SkCanvas(device);
bsalomon@google.com230504d2012-09-27 16:04:54 +0000140 } else {
reed@google.com5957f472012-10-01 20:31:56 +0000141 return NULL;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000142 }
143 break;
144#endif
145 default:
146 SkASSERT(false);
reed@google.com5957f472012-10-01 20:31:56 +0000147 return NULL;
yangsu@google.com688823f2011-08-30 19:14:13 +0000148 }
reed@google.com5957f472012-10-01 20:31:56 +0000149 return NULL;
yangsu@google.com688823f2011-08-30 19:14:13 +0000150 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000151
yangsu@google.com688823f2011-08-30 19:14:13 +0000152 virtual void publishCanvas(SampleWindow::DeviceType dType,
153 SkCanvas* canvas,
bsalomon@google.com230504d2012-09-27 16:04:54 +0000154 SampleWindow* win) SK_OVERRIDE {
caryclark@google.com5987f582012-10-02 18:33:14 +0000155#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000156 if (NULL != fCurContext) {
157 fCurContext->flush();
158 }
caryclark@google.com5987f582012-10-02 18:33:14 +0000159#endif
bsalomon@google.com230504d2012-09-27 16:04:54 +0000160 win->present();
yangsu@google.com688823f2011-08-30 19:14:13 +0000161 }
162
bsalomon@google.com230504d2012-09-27 16:04:54 +0000163 virtual void windowSizeChanged(SampleWindow* win) SK_OVERRIDE {
164#if SK_SUPPORT_GPU
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000165 if (NULL != fCurContext) {
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000166 SkOSWindow::AttachmentInfo info;
167
168 win->attach(fBackend, fMSAASampleCount, &info);
yangsu@google.com688823f2011-08-30 19:14:13 +0000169
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000170 glBindFramebuffer(GL_FRAMEBUFFER, fLayerFBO);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000171 GrBackendRenderTargetDesc desc;
reed@google.com26deb232013-12-17 19:50:57 +0000172 desc.fWidth = SkScalarRoundToInt(win->width());
173 desc.fHeight = SkScalarRoundToInt(win->height());
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000174 desc.fConfig = kSkia8888_GrPixelConfig;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000175 desc.fRenderTargetHandle = fLayerFBO;
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000176 desc.fSampleCnt = info.fSampleCount;
177 desc.fStencilBits = info.fStencilBits;
178
bsalomon@google.com230504d2012-09-27 16:04:54 +0000179 SkSafeUnref(fCurRenderTarget);
bsalomon@google.comf67bd9d2013-02-07 16:23:58 +0000180 fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
yangsu@google.com688823f2011-08-30 19:14:13 +0000181 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000182#endif
yangsu@google.com688823f2011-08-30 19:14:13 +0000183 }
184
bsalomon@google.com230504d2012-09-27 16:04:54 +0000185 virtual GrContext* getGrContext() SK_OVERRIDE {
186#if SK_SUPPORT_GPU
187 return fCurContext;
188#else
189 return NULL;
190#endif
191 }
yangsu@google.com688823f2011-08-30 19:14:13 +0000192
bsalomon@google.com11959252012-04-06 20:13:38 +0000193 virtual GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
bsalomon@google.com230504d2012-09-27 16:04:54 +0000194#if SK_SUPPORT_GPU
195 return fCurRenderTarget;
196#else
197 return NULL;
198#endif
bsalomon@google.com11959252012-04-06 20:13:38 +0000199 }
bsalomon@google.com230504d2012-09-27 16:04:54 +0000200
201 bool isUsingGL() const { return SkOSWindow::kNone_BackEndType != fBackend; }
202
yangsu@google.com688823f2011-08-30 19:14:13 +0000203private:
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000204
bsalomon@google.com230504d2012-09-27 16:04:54 +0000205#if SK_SUPPORT_GPU
206 GrContext* fCurContext;
207 const GrGLInterface* fCurIntf;
208 GrRenderTarget* fCurRenderTarget;
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000209 int fMSAASampleCount;
210 GLint fLayerFBO;
bsalomon@google.com230504d2012-09-27 16:04:54 +0000211#endif
212
213 SkOSWindow::SkBackEndTypes fBackend;
214
215 typedef SampleWindow::DeviceManager INHERITED;
yangsu@google.com688823f2011-08-30 19:14:13 +0000216};
217
218////////////////////////////////////////////////////////////////////////////////
219@implementation SkSampleUIView
220
221@synthesize fTitle, fRasterLayer, fGLLayer;
222
223#include "SkApplication.h"
224#include "SkEvent.h"
225#include "SkWindow.h"
226
yangsu@google.com688823f2011-08-30 19:14:13 +0000227struct FPSState {
228 static const int FRAME_COUNT = 60;
229
230 CFTimeInterval fNow0, fNow1;
231 CFTimeInterval fTime0, fTime1, fTotalTime;
232 int fFrameCounter;
yangsu@google.com688823f2011-08-30 19:14:13 +0000233 SkString str;
234 FPSState() {
235 fTime0 = fTime1 = fTotalTime = 0;
236 fFrameCounter = 0;
237 }
238
239 void startDraw() {
240 fNow0 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000241 }
242
243 void endDraw() {
244 fNow1 = CACurrentMediaTime();
yangsu@google.com688823f2011-08-30 19:14:13 +0000245 }
246
247 void flush(SkOSWindow* hwnd) {
248 CFTimeInterval now2 = CACurrentMediaTime();
249
250 fTime0 += fNow1 - fNow0;
251 fTime1 += now2 - fNow1;
252
253 if (++fFrameCounter == FRAME_COUNT) {
254 CFTimeInterval totalNow = CACurrentMediaTime();
255 fTotalTime = totalNow - fTotalTime;
256
257 //SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
258 //SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
259 //str.printf(" ms: %d [%d], fps: %3.1f", msTotal, ms0,
260 // FRAME_COUNT / fTotalTime);
261 str.printf(" fps:%3.1f", FRAME_COUNT / fTotalTime);
262 hwnd->setTitle(NULL);
263 fTotalTime = totalNow;
264 fTime0 = fTime1 = 0;
265 fFrameCounter = 0;
266 }
267 }
268};
269
270static FPSState gFPS;
271
272#define FPS_StartDraw() gFPS.startDraw()
273#define FPS_EndDraw() gFPS.endDraw()
274#define FPS_Flush(wind) gFPS.flush(wind)
275
276///////////////////////////////////////////////////////////////////////////////
277
278- (id)initWithDefaults {
279 if (self = [super initWithDefaults]) {
280 fRedrawRequestPending = false;
281 fFPSState = new FPSState;
282
283#ifdef USE_GL_1
284 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
285#else
286 fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
287#endif
288
289 if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
290 {
291 [self release];
292 return nil;
293 }
294
295 // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
296 glGenFramebuffers(1, &fGL.fFramebuffer);
297 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
298
299 glGenRenderbuffers(1, &fGL.fRenderbuffer);
300 glGenRenderbuffers(1, &fGL.fStencilbuffer);
301
302 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
303 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fGL.fRenderbuffer);
304
305 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
306 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fGL.fStencilbuffer);
307
308 self.fGLLayer = [CAEAGLLayer layer];
309 fGLLayer.bounds = self.bounds;
310 fGLLayer.anchorPoint = CGPointMake(0, 0);
311 fGLLayer.opaque = TRUE;
312 [self.layer addSublayer:fGLLayer];
313 fGLLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
314 [NSNumber numberWithBool:NO],
315 kEAGLDrawablePropertyRetainedBacking,
316 SKGL_CONFIG,
317 kEAGLDrawablePropertyColorFormat,
318 nil];
319
320 self.fRasterLayer = [CALayer layer];
321 fRasterLayer.anchorPoint = CGPointMake(0, 0);
322 fRasterLayer.opaque = TRUE;
323 [self.layer addSublayer:fRasterLayer];
324
caryclark@google.com5987f582012-10-02 18:33:14 +0000325 NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
yangsu@google.com688823f2011-08-30 19:14:13 +0000326 [NSNull null], @"onOrderOut",
327 [NSNull null], @"sublayers",
328 [NSNull null], @"contents",
329 [NSNull null], @"bounds",
330 nil];
331 fGLLayer.actions = newActions;
332 fRasterLayer.actions = newActions;
333 [newActions release];
334
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000335 fDevManager = new SkiOSDeviceManager(fGL.fFramebuffer);
caryclark@google.com5987f582012-10-02 18:33:14 +0000336 static char* kDummyArgv = const_cast<char*>("dummyExecutableName");
bsalomon@google.com230504d2012-09-27 16:04:54 +0000337 fWind = new SampleWindow(self, 1, &kDummyArgv, fDevManager);
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000338
commit-bot@chromium.orgb45c56e2014-02-18 23:32:05 +0000339 fWind->resize(self.frame.size.width, self.frame.size.height,
commit-bot@chromium.org149e9a12014-04-09 20:45:29 +0000340 kN32_SkColorType);
yangsu@google.com688823f2011-08-30 19:14:13 +0000341 }
342 return self;
343}
344
345- (void)dealloc {
346 delete fDevManager;
347 delete fFPSState;
348 self.fRasterLayer = nil;
349 self.fGLLayer = nil;
350 [fGL.fContext release];
351 [super dealloc];
352}
353
354- (void)layoutSubviews {
355 int W, H;
356
357 // Allocate color buffer backing based on the current layer size
358 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
359 [fGL.fContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:fGLLayer];
360
361 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &fGL.fWidth);
362 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &fGL.fHeight);
363
364 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fStencilbuffer);
365 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fGL.fWidth, fGL.fHeight);
366
367 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
368 NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
369 }
370
371 if (fDevManager->isUsingGL()) {
372 W = fGL.fWidth;
373 H = fGL.fHeight;
374 CGRect rect = CGRectMake(0, 0, W, H);
375 fGLLayer.bounds = rect;
376 }
377 else {
378 CGRect rect = self.bounds;
379 W = (int)CGRectGetWidth(rect);
380 H = (int)CGRectGetHeight(rect);
381 fRasterLayer.bounds = rect;
382 }
383
384 printf("---- layoutSubviews %d %d\n", W, H);
385 fWind->resize(W, H);
386 fWind->inval(NULL);
387}
388
389///////////////////////////////////////////////////////////////////////////////
390
391- (void)drawWithCanvas:(SkCanvas*)canvas {
392 fRedrawRequestPending = false;
393 fFPSState->startDraw();
394 fWind->draw(canvas);
395 fFPSState->endDraw();
396#ifdef FORCE_REDRAW
397 fWind->inval(NULL);
398#endif
399 fFPSState->flush(fWind);
400}
401
402- (void)drawInGL {
403 // This application only creates a single context which is already set current at this point.
404 // This call is redundant, but needed if dealing with multiple contexts.
405 [EAGLContext setCurrentContext:fGL.fContext];
406
407 // This application only creates a single default framebuffer which is already bound at this point.
408 // This call is redundant, but needed if dealing with multiple framebuffers.
409 glBindFramebuffer(GL_FRAMEBUFFER, fGL.fFramebuffer);
410
411 GLint scissorEnable;
412 glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
413 glDisable(GL_SCISSOR_TEST);
414 glClearColor(0,0,0,0);
415 glClear(GL_COLOR_BUFFER_BIT);
416 if (scissorEnable) {
417 glEnable(GL_SCISSOR_TEST);
418 }
419 glViewport(0, 0, fGL.fWidth, fGL.fHeight);
420
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000421
reed@google.com5957f472012-10-01 20:31:56 +0000422 SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
yangsu@google.com688823f2011-08-30 19:14:13 +0000423 // if we're not "retained", then we have to always redraw everything.
424 // This call forces us to ignore the fDirtyRgn, and draw everywhere.
425 // If we are "retained", we can skip this call (as the raster case does)
426 fWind->forceInvalAll();
bsalomon@google.comcca3c8f2012-09-28 16:56:28 +0000427
reed@google.com5957f472012-10-01 20:31:56 +0000428 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000429
430 // This application only creates a single color renderbuffer which is already bound at this point.
431 // This call is redundant, but needed if dealing with multiple renderbuffers.
432 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
433 [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER];
434
yangsu@google.com688823f2011-08-30 19:14:13 +0000435}
436
437- (void)drawInRaster {
reed@google.com5957f472012-10-01 20:31:56 +0000438 SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
439 [self drawWithCanvas:canvas];
yangsu@google.com688823f2011-08-30 19:14:13 +0000440 CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
441 fRasterLayer.contents = (id)cgimage;
442 CGImageRelease(cgimage);
443}
444
445- (void)forceRedraw {
446 if (fDevManager->isUsingGL())
447 [self drawInGL];
448 else
449 [self drawInRaster];
450}
451
452///////////////////////////////////////////////////////////////////////////////
453
454- (void)setSkTitle:(const char *)title {
455 NSString* text = [NSString stringWithUTF8String:title];
456 if ([text length] > 0)
457 self.fTitle = text;
458
459 if (fTitleItem && fTitle) {
460 fTitleItem.title = [NSString stringWithFormat:@"%@%@", fTitle,
461 [NSString stringWithUTF8String:fFPSState->str.c_str()]];
462 }
463}
464
465- (void)postInvalWithRect:(const SkIRect*)r {
466 if (!fRedrawRequestPending) {
467 fRedrawRequestPending = true;
468 bool gl = fDevManager->isUsingGL();
469 [CATransaction begin];
470 [CATransaction setAnimationDuration:0];
471 fRasterLayer.hidden = gl;
472 fGLLayer.hidden = !gl;
473 [CATransaction commit];
474 if (gl) {
475 [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
476 }
477 else {
478 [self performSelector:@selector(drawInRaster) withObject:nil afterDelay:0];
479 [self setNeedsDisplay];
480 }
481 }
482}
483
bsalomon@google.com64cc8102013-03-05 20:06:05 +0000484- (void)getAttachmentInfo:(SkOSWindow::AttachmentInfo*)info {
485 glBindRenderbuffer(GL_RENDERBUFFER, fGL.fRenderbuffer);
486 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
487 GL_RENDERBUFFER_STENCIL_SIZE,
488 &info->fStencilBits);
489 glGetRenderbufferParameteriv(GL_RENDERBUFFER,
490 GL_RENDERBUFFER_SAMPLES_APPLE,
491 &info->fSampleCount);
492}
493
yangsu@google.com688823f2011-08-30 19:14:13 +0000494@end