Updated SkUIView to use the current code, added a default gl interface for ios

http://codereview.appspot.com/4717043/


git-svn-id: http://skia.googlecode.com/svn/trunk@1855 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
yangsu@google.com 2011-07-13 22:05:00 +00:00
parent 0b96a84ca1
commit bd3e3202ad
3 changed files with 249 additions and 122 deletions

View File

@ -12,7 +12,6 @@ class SkEvent;
@interface SkUIView : UIView <UIAccelerometerDelegate> {
BOOL fRedrawRequestPending;
SkOSWindow* fWind;
SkMatrix fMatrix, fLocalMatrix;
bool fNeedGestureEnded;
@ -38,8 +37,6 @@ class SkEvent;
GLint fHeight;
} fGL;
UILabel* fTitleLabel;
enum Backend {
kGL_Backend,
kRaster_Backend,
@ -48,14 +45,20 @@ class SkEvent;
// these are visible to DetailViewController
Backend fBackend;
bool fComplexClip;
UINavigationItem* fTitle;
SkOSWindow* fWind;
}
@property (nonatomic, assign) SkOSWindow *fWind;
@property (nonatomic, retain) UILabel* fTitleLabel;
@property (nonatomic, retain) UINavigationItem* fTitle;
@property (nonatomic, assign) Backend fBackend;
@property (nonatomic, assign) bool fComplexClip;
@property (nonatomic, assign, setter=setWarpState) bool fUseWarp;
- (void)initGestures;
- (void)flushLocalMatrix;
- (void)setSkTitle:(const char*)title;
- (void)postInvalWithRect:(const SkIRect*)rectOrNil;
- (BOOL)onHandleEvent:(const SkEvent&)event;

View File

@ -0,0 +1,156 @@
/*
Copyright 2011 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "GrGLInterface.h"
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
void GrGLSetDefaultGLInterface() {
static GrGLInterface gDefaultInterface;
static bool gDefaultInterfaceInit;
if (!gDefaultInterfaceInit) {
gDefaultInterface.fNPOTRenderTargetSupport = kProbe_GrGLCapability;
gDefaultInterface.fMinRenderTargetHeight = kProbe_GrGLCapability;
gDefaultInterface.fMinRenderTargetWidth = kProbe_GrGLCapability;
gDefaultInterface.fActiveTexture = glActiveTexture;
gDefaultInterface.fAttachShader = glAttachShader;
gDefaultInterface.fBindAttribLocation = glBindAttribLocation;
gDefaultInterface.fBindBuffer = glBindBuffer;
gDefaultInterface.fBindTexture = glBindTexture;
gDefaultInterface.fBlendColor = glBlendColor;
gDefaultInterface.fBlendFunc = glBlendFunc;
gDefaultInterface.fBufferData = (GrGLBufferDataProc)glBufferData;
gDefaultInterface.fBufferSubData = (GrGLBufferSubDataProc)glBufferSubData;
gDefaultInterface.fClear = glClear;
gDefaultInterface.fClearColor = glClearColor;
gDefaultInterface.fClearStencil = glClearStencil;
gDefaultInterface.fClientActiveTexture = glClientActiveTexture;
gDefaultInterface.fColorMask = glColorMask;
gDefaultInterface.fColorPointer = glColorPointer;
gDefaultInterface.fColor4ub = glColor4ub;
gDefaultInterface.fCompileShader = glCompileShader;
gDefaultInterface.fCompressedTexImage2D = glCompressedTexImage2D;
gDefaultInterface.fCreateProgram = glCreateProgram;
gDefaultInterface.fCreateShader = glCreateShader;
gDefaultInterface.fCullFace = glCullFace;
gDefaultInterface.fDeleteBuffers = glDeleteBuffers;
gDefaultInterface.fDeleteProgram = glDeleteProgram;
gDefaultInterface.fDeleteShader = glDeleteShader;
gDefaultInterface.fDeleteTextures = glDeleteTextures;
gDefaultInterface.fDepthMask = glDepthMask;
gDefaultInterface.fDisable = glDisable;
gDefaultInterface.fDisableClientState = glDisableClientState;
gDefaultInterface.fDisableVertexAttribArray =
glDisableVertexAttribArray;
gDefaultInterface.fDrawArrays = glDrawArrays;
gDefaultInterface.fDrawElements = glDrawElements;
gDefaultInterface.fEnable = glEnable;
gDefaultInterface.fEnableClientState = glEnableClientState;
gDefaultInterface.fEnableVertexAttribArray = glEnableVertexAttribArray;
gDefaultInterface.fFrontFace = glFrontFace;
gDefaultInterface.fGenBuffers = glGenBuffers;
gDefaultInterface.fGetBufferParameteriv = glGetBufferParameteriv;
gDefaultInterface.fGetError = glGetError;
gDefaultInterface.fGetIntegerv = glGetIntegerv;
gDefaultInterface.fGetProgramInfoLog = glGetProgramInfoLog;
gDefaultInterface.fGetProgramiv = glGetProgramiv;
gDefaultInterface.fGetShaderInfoLog = glGetShaderInfoLog;
gDefaultInterface.fGetShaderiv = glGetShaderiv;
gDefaultInterface.fGetString = glGetString;
gDefaultInterface.fGenTextures = glGenTextures;
gDefaultInterface.fGetUniformLocation = glGetUniformLocation;
gDefaultInterface.fLineWidth = glLineWidth;
gDefaultInterface.fLinkProgram = glLinkProgram;
gDefaultInterface.fLoadMatrixf = glLoadMatrixf;
gDefaultInterface.fMatrixMode = glMatrixMode;
gDefaultInterface.fPointSize = glPointSize;
gDefaultInterface.fPixelStorei = glPixelStorei;
gDefaultInterface.fReadPixels = glReadPixels;
gDefaultInterface.fScissor = glScissor;
gDefaultInterface.fShadeModel = glShadeModel;
gDefaultInterface.fShaderSource = glShaderSource;
gDefaultInterface.fStencilFunc = glStencilFunc;
gDefaultInterface.fStencilFuncSeparate = glStencilFuncSeparate;
gDefaultInterface.fStencilMask = glStencilMask;
gDefaultInterface.fStencilMaskSeparate = glStencilMaskSeparate;
gDefaultInterface.fStencilOp = glStencilOp;
gDefaultInterface.fStencilOpSeparate = glStencilOpSeparate;
gDefaultInterface.fTexCoordPointer = glTexCoordPointer;
gDefaultInterface.fTexEnvi = glTexEnvi;
// mac uses GLenum for internalFormat param (non-standard)
// amounts to int vs. uint.
gDefaultInterface.fTexImage2D = (GrGLTexImage2DProc)glTexImage2D;
gDefaultInterface.fTexParameteri = glTexParameteri;
gDefaultInterface.fTexSubImage2D = glTexSubImage2D;
gDefaultInterface.fUniform1f = glUniform1f;
gDefaultInterface.fUniform1i = glUniform1i;
gDefaultInterface.fUniform1fv = glUniform1fv;
gDefaultInterface.fUniform1iv = glUniform1iv;
gDefaultInterface.fUniform2f = glUniform2f;
gDefaultInterface.fUniform2i = glUniform2i;
gDefaultInterface.fUniform2fv = glUniform2fv;
gDefaultInterface.fUniform2iv = glUniform2iv;
gDefaultInterface.fUniform3f = glUniform3f;
gDefaultInterface.fUniform3i = glUniform3i;
gDefaultInterface.fUniform3fv = glUniform3fv;
gDefaultInterface.fUniform3iv = glUniform3iv;
gDefaultInterface.fUniform4f = glUniform4f;
gDefaultInterface.fUniform4i = glUniform4i;
gDefaultInterface.fUniform4fv = glUniform4fv;
gDefaultInterface.fUniform4iv = glUniform4iv;
gDefaultInterface.fUniform4fv = glUniform4fv;
gDefaultInterface.fUniformMatrix2fv = glUniformMatrix2fv;
gDefaultInterface.fUniformMatrix3fv = glUniformMatrix3fv;
gDefaultInterface.fUniformMatrix4fv = glUniformMatrix4fv;
gDefaultInterface.fUseProgram = glUseProgram;
gDefaultInterface.fVertexAttrib4fv = glVertexAttrib4fv;
gDefaultInterface.fVertexAttribPointer = glVertexAttribPointer;
gDefaultInterface.fVertexPointer = glVertexPointer;
gDefaultInterface.fViewport = glViewport;
gDefaultInterface.fGenFramebuffers = glGenFramebuffers;
gDefaultInterface.fBindFramebuffer = glBindFramebuffer;
gDefaultInterface.fFramebufferTexture2D = glFramebufferTexture2D;
gDefaultInterface.fCheckFramebufferStatus = glCheckFramebufferStatus;
gDefaultInterface.fDeleteFramebuffers = glDeleteFramebuffers;
gDefaultInterface.fRenderbufferStorage = glRenderbufferStorage;
gDefaultInterface.fGenRenderbuffers = glGenRenderbuffers;
gDefaultInterface.fDeleteRenderbuffers = glDeleteRenderbuffers;
gDefaultInterface.fFramebufferRenderbuffer = glFramebufferRenderbuffer;
gDefaultInterface.fBindRenderbuffer = glBindRenderbuffer;
#if GL_OES_mapbuffer
gDefaultInterface.fMapBuffer = glMapBufferOES;
gDefaultInterface.fUnmapBuffer = glUnmapBufferOES;
#endif
#if GL_APPLE_framebuffer_multisample
gDefaultInterface.fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleAPPLE;
gDefaultInterface.fResolveMultisampleFramebuffer = glResolveMultisampleFramebufferAPPLE;
#endif
gDefaultInterface.fBindFragDataLocationIndexed = NULL;
gDefaultInterface.fBindingsExported = kES2_GrGLBinding;
gDefaultInterfaceInit = true;
}
GrGLSetGLInterface(&gDefaultInterface);
}

View File

@ -1,7 +1,8 @@
#import "SkUIView.h"
#include <QuartzCore/QuartzCore.h>
#include "SkGpuCanvas.h"
//#include "SkGpuCanvas.h"
#include "SkGpuDevice.h"
#include "SkCGUtils.h"
#include "GrContext.h"
@ -32,7 +33,7 @@ static bool should_draw() {
#endif
//#define USE_GL_1
#define USE_GL_2
//#define USE_GL_2
#if defined(USE_GL_1) || defined(USE_GL_2)
#define USE_GL
@ -42,7 +43,7 @@ static bool should_draw() {
@synthesize fWind;
@synthesize fTitleLabel;
@synthesize fTitle;
@synthesize fBackend;
@synthesize fComplexClip;
@synthesize fUseWarp;
@ -56,7 +57,7 @@ extern SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
#define kREDRAW_UIVIEW_GL "sk_redraw_uiview_gl_iOS"
#define TITLE_HEIGHT 44
#define TITLE_HEIGHT 0
static const float SCALE_FOR_ZOOM_LENS = 4.0;
#define Y_OFFSET_FOR_ZOOM_LENS 200
@ -156,8 +157,8 @@ static FPSState gFPS;
fUseWarp = false;
fRedrawRequestPending = false;
// FIXME: If iOS has argc & argv, pass them here.
fWind = create_sk_window(self, 0, NULL);
fWind->setConfig(SKWIND_CONFIG);
//fWind = create_sk_window(self, 0, NULL);
//fWind->setConfig(SKWIND_CONFIG);
fMatrix.reset();
fLocalMatrix.reset();
fNeedGestureEnded = false;
@ -295,15 +296,14 @@ static void zoom_around(SkCanvas* canvas, float cx, float cy, float zoom) {
#ifdef SHOULD_COUNTER_INIT
gShouldCounter = SHOULD_COUNTER_INIT;
#endif
{
int saveCount = canvas->save();
canvas->concat(matrix);
// SkRect r = { 10, 10, 500, 600 }; canvas->clipRect(r);
// SkRect r = { 10, 10, 500, 600 }; canvas->clipRect(r);
fWind->draw(canvas);
canvas->restoreToCount(saveCount);
}
if (fZoomAround) {
zoom_around(canvas, fZoomAroundX, fZoomAroundY, SCALE_FOR_ZOOM_LENS);
canvas->concat(matrix);
@ -328,6 +328,7 @@ static void zoom_around(SkCanvas* canvas, float cx, float cy, float zoom) {
if ([self respondsToSelector:@selector(setContentScaleFactor:)]) {
self.contentScaleFactor = gScreenScale;
}
// Allocate color buffer backing based on the current layer size
glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
[fGL.fContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer];
@ -335,14 +336,15 @@ static void zoom_around(SkCanvas* canvas, float cx, float cy, float zoom) {
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &fGL.fWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &fGL.fHeight);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_STENCIL_INDEX8_OES, fGL.fWidth, fGL.fHeight);
if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
{
NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
}
glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_STENCIL_INDEX8_OES, fGL.fWidth, fGL.fHeight);
W = fGL.fWidth;
H = fGL.fHeight;
#else
@ -363,9 +365,9 @@ static GrContext* get_global_grctx() {
// should be pthread-local at least
if (NULL == gCtx) {
#ifdef USE_GL_1
gCtx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, 0);
gCtx = GrContext::Create(kOpenGL_Fixed_GrEngine, 0);
#else
gCtx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, 0);
gCtx = GrContext::Create(kOpenGL_Shaders_GrEngine, 0);
#endif
}
return gCtx;
@ -478,17 +480,22 @@ static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float
if (scissorEnable) {
glEnable(GL_SCISSOR_TEST);
}
glViewport(0, 0, fWind->width(), fWind->height());
GrContext* ctx = get_global_grctx();
SkGpuCanvas origCanvas(ctx);
origCanvas.setBitmapDevice(fWind->getBitmap());
// gl->reset();
SkGpuCanvas glCanvas(ctx);
//SkGpuCanvas origCanvas(ctx);
//origCanvas.setBitmapDevice(fWind->getBitmap());
//gl->reset();
SkCanvas glCanvas;
SkGpuDevice* dev = new SkGpuDevice(ctx, SkGpuDevice::Current3DApiRenderTarget());
glCanvas.setDevice(dev)->unref();
SkCanvas rasterCanvas;
SkCanvas* canvas;
SkDevice* dev = NULL;
//SkDevice* dev = NULL;
switch (fBackend) {
case kRaster_Backend:
@ -499,18 +506,18 @@ static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float
break;
}
if (fUseWarp || fWarpState.isActive()) {
if (kGL_Backend == fBackend) {
dev = origCanvas.createDevice(fWind->getBitmap(), true);
canvas->setDevice(dev)->unref();
} else {
canvas->setBitmapDevice(fWind->getBitmap());
dev = canvas->getDevice();
}
} else {
canvas->setBitmapDevice(fWind->getBitmap());
dev = NULL;
}
// if (fUseWarp || fWarpState.isActive()) {
// if (kGL_Backend == fBackend) {
// dev = origCanvas.createDevice(fWind->getBitmap(), true);
// canvas->setDevice(dev)->unref();
// } else {
// canvas->setBitmapDevice(fWind->getBitmap());
// dev = canvas->getDevice();
// }
// } else {
// canvas->setBitmapDevice(fWind->getBitmap());
// dev = NULL;
// }
canvas->translate(0, TITLE_HEIGHT);
@ -523,15 +530,15 @@ static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float
[self drawWithCanvas:canvas];
FPS_EndDraw();
if (dev) {
draw_device(&origCanvas, dev, fWind->width(), fWind->height(),
fWarpState.evaluate());
} else {
if (kRaster_Backend == fBackend) {
origCanvas.drawBitmap(fWind->getBitmap(), 0, 0, NULL);
}
// else GL - we're already on screen
}
// if (dev) {
// draw_device(&origCanvas, dev, fWind->width(), fWind->height(),
// fWarpState.evaluate());
// } else {
// if (kRaster_Backend == fBackend) {
// origCanvas.drawBitmap(fWind->getBitmap(), 0, 0, NULL);
// }
// // else GL - we're already on screen
// }
show_fontcache(ctx, canvas);
ctx->flush(false);
@ -562,13 +569,13 @@ static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float
#else // raster case
- (void)drawRect:(CGRect)rect {
CGContextRef cg = UIGraphicsGetCurrentContext();
SkCanvas* canvas = NULL;
SkCanvas canvas;
canvas.setBitmapDevice(fWind->getBitmap());
FPS_StartDraw();
[self drawWithCanvas:canvas];
[self drawWithCanvas:&canvas];
FPS_EndDraw();
CGContextRef cg = UIGraphicsGetCurrentContext();
SkCGDrawBitmap(cg, fWind->getBitmap(), 0, TITLE_HEIGHT);
FPS_Flush(fWind);
@ -629,35 +636,6 @@ static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float
}
}
- (void)handleDTapGesture:(UIGestureRecognizer*)sender {
[self flushLocalMatrix];
fMatrix.reset();
}
static float discretize(float x) {
return (int)x;
}
- (void)handlePanGesture:(UIPanGestureRecognizer*)sender {
[self commonHandleGesture:sender];
CGPoint delta = [sender translationInView:self];
delta.x *= gScreenScale;
delta.y *= gScreenScale;
// avoid flickering where the drawing might toggle in and out of a pixel
// center if translated by a fractional value
delta.x = discretize(delta.x);
delta.y = discretize(delta.y);
fLocalMatrix.setTranslate(delta.x, delta.y);
[self localMatrixWithGesture:sender];
if (UIGestureRecognizerStateEnded == sender.state) {
CGPoint velocity = [sender velocityInView:self];
fFlingState.reset(velocity.x, velocity.y);
fNeedGestureEnded = true;
}
}
- (float)limitTotalZoom:(float)scale {
// this query works 'cause we know that we're square-scale w/ no skew/rotation
const float curr = fMatrix[0];
@ -670,33 +648,6 @@ static float discretize(float x) {
return scale;
}
- (void)handleScaleGesture:(UIPinchGestureRecognizer*)sender {
[self commonHandleGesture:sender];
if ([sender numberOfTouches] == 2) {
float scale = sender.scale;
CGPoint p0 = [sender locationOfTouch:0 inView:self];
CGPoint p1 = [sender locationOfTouch:0 inView:self];
float cx = (p0.x + p1.x) * 0.5;
float cy = (p0.y + p1.y) * 0.5;
if (fNeedFirstPinch) {
fFirstPinchX = cx;
fFirstPinchY = cy;
fNeedFirstPinch = false;
}
scale = [self limitTotalZoom:scale];
fLocalMatrix.setTranslate(-fFirstPinchX, -fFirstPinchY);
fLocalMatrix.postScale(scale, scale);
fLocalMatrix.postTranslate(cx, cy);
[self localMatrixWithGesture:sender];
} else {
[self flushLocalMatrix];
}
}
- (void)handleLongPressGesture:(UILongPressGestureRecognizer*)sender {
[self commonHandleGesture:sender];
@ -727,20 +678,38 @@ static float discretize(float x) {
[gesture release];
}
//Gesture Handlers
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint loc = [touch locationInView:self];
fWind->handleClick(loc.x, loc.y, SkView::Click::kDown_State, touch);
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint loc = [touch locationInView:self];
fWind->handleClick(loc.x, loc.y, SkView::Click::kMoved_State, touch);
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint loc = [touch locationInView:self];
fWind->handleClick(loc.x, loc.y, SkView::Click::kUp_State, touch);
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint loc = [touch locationInView:self];
fWind->handleClick(loc.x, loc.y, SkView::Click::kUp_State, touch);
}
}
- (void)initGestures {
UITapGestureRecognizer* tapG = [UITapGestureRecognizer alloc];
[tapG initWithTarget:self action:@selector(handleDTapGesture:)];
tapG.numberOfTapsRequired = 2;
[self addAndReleaseGesture:tapG];
UIPanGestureRecognizer* panG = [UIPanGestureRecognizer alloc];
[panG initWithTarget:self action:@selector(handlePanGesture:)];
[self addAndReleaseGesture:panG];
UIPinchGestureRecognizer* pinchG = [UIPinchGestureRecognizer alloc];
[pinchG initWithTarget:self action:@selector(handleScaleGesture:)];
[self addAndReleaseGesture:pinchG];
UILongPressGestureRecognizer* longG = [UILongPressGestureRecognizer alloc];
[longG initWithTarget:self action:@selector(handleLongPressGesture:)];
[self addAndReleaseGesture:longG];
@ -807,9 +776,8 @@ static float weighted_average(float newv, float oldv) {
///////////////////////////////////////////////////////////////////////////////
- (void)setSkTitle:(const char *)title {
if (fTitleLabel) {
fTitleLabel.text = [NSString stringWithUTF8String:title];
[fTitleLabel setNeedsDisplay];
if (fTitle) {
fTitle.title = [NSString stringWithUTF8String:title];
}
}