Added run-time switching between OpenGL & ANGLE in SampleApp

http://codereview.appspot.com/5969044/



git-svn-id: http://skia.googlecode.com/svn/trunk@3555 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
robertphillips@google.com 2012-03-30 14:47:53 +00:00
parent 10e04bf1c5
commit 53e96a14ca
4 changed files with 910 additions and 787 deletions

View File

@ -26,20 +26,19 @@ public:
void updateSize();
static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
bool attachGL();
void detachGL();
void presentGL();
enum SkBackEndTypes {
kNone_BackEndType,
kNativeGL_BackEndType,
#if SK_ANGLE
bool attachANGLE();
void detachANGLE();
void presentANGLE();
kANGLE_BackEndType,
#endif
kD3D9_BackEndType
};
bool attachD3D9();
void detachD3D9();
void presentD3D9();
bool attach(SkBackEndTypes attachType);
void detach();
void present();
void* d3d9Device() { return fD3D9Device; }
@ -73,13 +72,26 @@ private:
angle::EGLSurface fSurface;
#endif
bool fGLAttached;
void* fD3D9Device;
bool fD3D9Attached;
HMENU fMBar;
SkBackEndTypes fAttached;
bool attachGL();
void detachGL();
void presentGL();
#if SK_ANGLE
bool attachANGLE();
void detachANGLE();
void presentANGLE();
#endif
bool attachD3D9();
void detachD3D9();
void presentD3D9();
typedef SkWindow INHERITED;
};

View File

@ -53,7 +53,12 @@ SkTDArray<char> gTempDataStore;
#endif
#define USE_ARROWS_FOR_ZOOM true
//#define DEFAULT_TO_GPU
#if SK_ANGLE
//#define DEFAULT_TO_ANGLE 1
#else
//#define DEFAULT_TO_GPU 1
#endif
extern SkView* create_overview(int, const SkViewFactory*[]);
extern bool is_overview(SkView* view);
@ -131,113 +136,129 @@ class SampleWindow::DefaultDeviceManager : public SampleWindow::DeviceManager {
public:
DefaultDeviceManager()
#if SK_ANGLE
: fUseAltContext(false)
#endif
{
fGrRenderTarget = NULL;
fGrContext = NULL;
fGL = NULL;
fNullGrContext = NULL;
fNullGrRenderTarget = NULL;
: fCurContext(NULL)
, fCurIntf(NULL)
, fCurRenderTarget(NULL)
, fBackend(kNone_BackEndType) {
}
virtual ~DefaultDeviceManager() {
SkSafeUnref(fGrRenderTarget);
SkSafeUnref(fGrContext);
SkSafeUnref(fGL);
SkSafeUnref(fNullGrContext);
SkSafeUnref(fNullGrRenderTarget);
SkSafeUnref(fCurContext);
SkSafeUnref(fCurIntf);
SkSafeUnref(fCurRenderTarget);
}
virtual void init(SampleWindow* win, bool useAltContext) {
#if SK_ANGLE
fUseAltContext = useAltContext;
#endif
bool result;
virtual void setUpBackend(SampleWindow* win) {
SkASSERT(kNone_BackEndType == fBackend);
fBackend = kNone_BackEndType;
switch (win->getDeviceType()) {
case kRaster_DeviceType:
// fallthrough
case kPicture_DeviceType:
// fallthrough
case kGPU_DeviceType:
// fallthrough
case kNullGPU_DeviceType:
// all these guys use the native backend
fBackend = kNativeGL_BackEndType;
break;
#if SK_ANGLE
if (useAltContext) {
result = win->attachANGLE();
} else
case kANGLE_DeviceType:
// ANGLE is really the only odd man out
fBackend = kANGLE_BackEndType;
break;
#endif
{
result = win->attachGL();
default:
SkASSERT(false);
break;
}
bool result = win->attach(fBackend);
if (!result) {
SkDebugf("Failed to initialize GL");
return;
}
if (NULL == fGL) {
SkASSERT(NULL == fCurIntf);
switch (win->getDeviceType()) {
case kRaster_DeviceType:
// fallthrough
case kPicture_DeviceType:
// fallthrough
case kGPU_DeviceType:
// all these guys use the native interface
fCurIntf = GrGLCreateNativeInterface();
break;
#if SK_ANGLE
if (useAltContext) {
fGL = GrGLCreateANGLEInterface();
} else
case kANGLE_DeviceType:
fCurIntf = GrGLCreateANGLEInterface();
break;
#endif
{
fGL = GrGLCreateNativeInterface();
}
GrAssert(NULL == fGrContext);
fGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine,
(GrPlatform3DContext) fGL);
case kNullGPU_DeviceType:
fCurIntf = GrGLCreateNullInterface();
break;
default:
SkASSERT(false);
break;
}
if (NULL == fGrContext || NULL == fGL) {
SkSafeUnref(fGrContext);
SkSafeUnref(fGL);
SkASSERT(NULL == fCurContext);
fCurContext = GrContext::Create(kOpenGL_Shaders_GrEngine,
(GrPlatform3DContext) fCurIntf);
if (NULL == fCurContext || NULL == fCurIntf) {
// We need some context and interface to see results
SkSafeUnref(fCurContext);
SkSafeUnref(fCurIntf);
SkDebugf("Failed to setup 3D");
#if SK_ANGLE
if (useAltContext) {
win->detachANGLE();
} else
#endif
{
win->detachGL();
}
}
if (NULL == fNullGrContext) {
const GrGLInterface* nullGL = GrGLCreateNullInterface();
fNullGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine,
(GrPlatform3DContext) nullGL);
nullGL->unref();
win->detach();
}
// call windowSizeChanged to create the render target
windowSizeChanged(win);
}
virtual bool supportsDeviceType(SampleWindow::DeviceType dType) {
switch (dType) {
case kRaster_DeviceType:
case kPicture_DeviceType: // fallthru
return true;
case kGPU_DeviceType:
return NULL != fGrContext && NULL != fGrRenderTarget;
case kNullGPU_DeviceType:
return NULL != fNullGrContext && NULL != fNullGrRenderTarget;
default:
return false;
}
virtual void tearDownBackend(SampleWindow *win) {
win->detach();
fBackend = kNone_BackEndType;
SkSafeUnref(fCurContext);
fCurContext = NULL;
SkSafeUnref(fCurIntf);
fCurIntf = NULL;
SkSafeUnref(fCurRenderTarget);
fCurRenderTarget = NULL;
}
virtual bool prepareCanvas(SampleWindow::DeviceType dType,
SkCanvas* canvas,
SampleWindow* win) {
switch (dType) {
case kGPU_DeviceType:
if (fGrContext) {
canvas->setDevice(new SkGpuDevice(fGrContext,
fGrRenderTarget))->unref();
} else {
return false;
}
break;
case kNullGPU_DeviceType:
if (fNullGrContext) {
canvas->setDevice(new SkGpuDevice(fNullGrContext,
fNullGrRenderTarget))->unref();
} else {
return false;
}
break;
case kRaster_DeviceType:
// fallthrough
case kPicture_DeviceType:
// fallthrough
#if SK_ANGLE
case kANGLE_DeviceType:
#endif
break;
case kGPU_DeviceType:
case kNullGPU_DeviceType:
if (fCurContext) {
canvas->setDevice(new SkGpuDevice(fCurContext,
fCurRenderTarget))->unref();
} else {
return false;
}
break;
default:
SkASSERT(false);
return false;
}
return true;
}
@ -245,85 +266,55 @@ public:
virtual void publishCanvas(SampleWindow::DeviceType dType,
SkCanvas* canvas,
SampleWindow* win) {
if (fGrContext) {
if (fCurContext) {
// in case we have queued drawing calls
fGrContext->flush();
if (NULL != fNullGrContext) {
fNullGrContext->flush();
}
if (dType != kGPU_DeviceType &&
dType != kNullGPU_DeviceType) {
fCurContext->flush();
if (kGPU_DeviceType != dType && kNullGPU_DeviceType != dType) {
// need to send the raster bits to the (gpu) window
fGrContext->setRenderTarget(fGrRenderTarget);
fCurContext->setRenderTarget(fCurRenderTarget);
const SkBitmap& bm = win->getBitmap();
fGrRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
fCurRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
kSkia8888_PM_GrPixelConfig,
bm.getPixels(),
bm.rowBytes());
}
}
#if SK_ANGLE
if (fUseAltContext) {
win->presentANGLE();
} else
#endif
{
win->presentGL();
}
win->present();
}
virtual void windowSizeChanged(SampleWindow* win) {
if (fGrContext) {
#if SK_ANGLE
if (fUseAltContext) {
win->attachANGLE();
} else
#endif
{
win->attachGL();
}
if (fCurContext) {
win->attach(fBackend);
GrPlatformRenderTargetDesc desc;
desc.fWidth = SkScalarRound(win->width());
desc.fHeight = SkScalarRound(win->height());
desc.fConfig = kSkia8888_PM_GrPixelConfig;
GR_GL_GetIntegerv(fGL, GR_GL_SAMPLES, &desc.fSampleCnt);
GR_GL_GetIntegerv(fGL, GR_GL_STENCIL_BITS, &desc.fStencilBits);
GR_GL_GetIntegerv(fCurIntf, GR_GL_SAMPLES, &desc.fSampleCnt);
GR_GL_GetIntegerv(fCurIntf, GR_GL_STENCIL_BITS, &desc.fStencilBits);
GrGLint buffer;
GR_GL_GetIntegerv(fGL, GR_GL_FRAMEBUFFER_BINDING, &buffer);
GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
desc.fRenderTargetHandle = buffer;
SkSafeUnref(fGrRenderTarget);
fGrRenderTarget = fGrContext->createPlatformRenderTarget(desc);
}
if (NULL != fNullGrContext) {
GrPlatformRenderTargetDesc desc;
desc.fWidth = SkScalarRound(win->width());
desc.fHeight = SkScalarRound(win->height());
desc.fConfig = kSkia8888_PM_GrPixelConfig;
desc.fStencilBits = 8;
desc.fSampleCnt = 0;
desc.fRenderTargetHandle = 0;
fNullGrRenderTarget = fNullGrContext->createPlatformRenderTarget(desc);
SkSafeUnref(fCurRenderTarget);
fCurRenderTarget = fCurContext->createPlatformRenderTarget(desc);
}
}
virtual GrContext* getGrContext(SampleWindow::DeviceType dType) {
if (kNullGPU_DeviceType == dType) {
return fNullGrContext;
} else {
return fGrContext;
}
virtual GrContext* getGrContext() {
return fCurContext;
}
private:
#if SK_ANGLE
bool fUseAltContext;
#endif
GrContext* fGrContext;
const GrGLInterface* fGL;
GrRenderTarget* fGrRenderTarget;
GrContext* fNullGrContext;
GrRenderTarget* fNullGrRenderTarget;
GrContext* fCurContext;
const GrGLInterface* fCurIntf;
GrRenderTarget* fCurRenderTarget;
SkOSWindow::SkBackEndTypes fBackend;
typedef SampleWindow::DeviceManager INHERITED;
};
///////////////
@ -644,6 +635,9 @@ static inline SampleWindow::DeviceType cycle_devicetype(SampleWindow::DeviceType
static const SampleWindow::DeviceType gCT[] = {
SampleWindow::kPicture_DeviceType,
SampleWindow::kGPU_DeviceType,
#if SK_ANGLE
SampleWindow::kANGLE_DeviceType,
#endif
SampleWindow::kRaster_DeviceType, // skip the null gpu device in normal cycling
SampleWindow::kRaster_DeviceType
};
@ -669,7 +663,6 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev
const char* resourcePath = NULL;
fCurrIndex = -1;
bool useAltContext = false;
const char* const commandName = argv[0];
char* const* stop = argv + argc;
@ -688,12 +681,6 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev
}
}
}
#if SK_ANGLE
else if (strcmp(*argv, "--angle") == 0) {
argv++;
useAltContext = true;
}
#endif
else {
usage(commandName);
}
@ -720,11 +707,15 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev
fPicture = NULL;
#ifdef DEFAULT_TO_GPU
fDeviceType = kGPU_DeviceType;
#else
fDeviceType = kRaster_DeviceType;
#if DEFAULT_TO_GPU
fDeviceType = kGPU_DeviceType;
#endif
#if SK_ANGLE && DEFAULT_TO_ANGLE
fDeviceType = kANGLE_DeviceType;
#endif
fUseClip = false;
fNClip = false;
fAnimating = false;
@ -764,7 +755,11 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev
int itemID;
itemID =fAppMenu.appendList("Device Type", "Device Type", sinkID, 0,
"Raster", "Picture", "OpenGL", NULL);
"Raster", "Picture", "OpenGL",
#if SK_ANGLE
"ANGLE",
#endif
NULL);
fAppMenu.assignKeyEquivalentToItem(itemID, 'd');
itemID = fAppMenu.appendTriState("AA", "AA", sinkID, fAAState);
fAppMenu.assignKeyEquivalentToItem(itemID, 'b');
@ -825,7 +820,7 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev
devManager->ref();
fDevManager = devManager;
}
fDevManager->init(this, useAltContext);
fDevManager->setUpBackend(this);
// If another constructor set our dimensions, ensure that our
// onSizeChange gets called.
@ -1133,7 +1128,12 @@ SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
} else {
switch (fDeviceType) {
case kRaster_DeviceType:
// fallthrough
case kGPU_DeviceType:
// fallthrough
#if SK_ANGLE
case kANGLE_DeviceType:
#endif
canvas = this->INHERITED::beforeChildren(canvas);
break;
case kPicture_DeviceType:
@ -1142,6 +1142,9 @@ SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
break;
case kNullGPU_DeviceType:
break;
default:
SkASSERT(false);
break;
}
}
@ -1628,11 +1631,9 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
this->updateTitle();
return true;
case '\\':
if (fDevManager->supportsDeviceType(kNullGPU_DeviceType)) {
fDeviceType= kNullGPU_DeviceType;
this->inval(NULL);
this->updateTitle();
}
this->setDeviceType(kNullGPU_DeviceType);
this->inval(NULL);
this->updateTitle();
return true;
case 'p':
{
@ -1663,8 +1664,15 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
}
void SampleWindow::setDeviceType(DeviceType type) {
if (type != fDeviceType && fDevManager->supportsDeviceType(fDeviceType))
fDeviceType = type;
if (type == fDeviceType)
return;
fDevManager->tearDownBackend(this);
fDeviceType = type;
fDevManager->setUpBackend(this);
this->updateTitle();
this->inval(NULL);
}
@ -1676,11 +1684,7 @@ void SampleWindow::toggleSlideshow() {
}
void SampleWindow::toggleRendering() {
DeviceType origDevType = fDeviceType;
do {
fDeviceType = cycle_devicetype(fDeviceType);
} while (origDevType != fDeviceType &&
!fDevManager->supportsDeviceType(fDeviceType));
this->setDeviceType(cycle_devicetype(fDeviceType));
this->updateTitle();
this->inval(NULL);
}
@ -1857,6 +1861,9 @@ static const char* gDeviceTypePrefix[] = {
"raster: ",
"picture: ",
"opengl: ",
#if SK_ANGLE
"angle: ",
#endif
"null-gl: "
};

View File

@ -36,6 +36,9 @@ public:
kRaster_DeviceType,
kPicture_DeviceType,
kGPU_DeviceType,
#if SK_ANGLE
kANGLE_DeviceType,
#endif
kNullGPU_DeviceType
};
/**
@ -47,12 +50,9 @@ public:
*/
class DeviceManager : public SkRefCnt {
public:
// called at end of SampleWindow cons
virtual void init(SampleWindow* win, bool useAltContext) = 0;
virtual void setUpBackend(SampleWindow* win) = 0;
// called when selecting a new device type
// can disallow a device type by returning false.
virtual bool supportsDeviceType(DeviceType dType) = 0;
virtual void tearDownBackend(SampleWindow* win) = 0;
// called before drawing. should install correct device
// type on the canvas. Will skip drawing if returns false.
@ -71,7 +71,7 @@ public:
virtual void windowSizeChanged(SampleWindow* win) = 0;
// return the GrContext backing gpu devices
virtual GrContext* getGrContext(DeviceType dType) = 0;
virtual GrContext* getGrContext() = 0;
};
SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
@ -85,7 +85,7 @@ public:
void toggleFPS();
void showOverview();
GrContext* getGrContext() const { return fDevManager->getGrContext(fDeviceType); }
GrContext* getGrContext() const { return fDevManager->getGrContext(); }
void setZoomCenter(float x, float y);
void changeZoomLevel(float delta);
@ -100,6 +100,8 @@ public:
SkData* getPDFData() { return fPDFData; }
void postInvalDelay();
DeviceType getDeviceType() const { return fDeviceType; }
protected:
virtual void onDraw(SkCanvas* canvas);
virtual bool onHandleKey(SkKey key);

File diff suppressed because it is too large Load Diff