2013-06-18 15:37:27 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2013 Google Inc.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
#include "SkExample.h"
|
2013-06-18 15:37:27 +00:00
|
|
|
|
|
|
|
#include "gl/GrGLUtil.h"
|
|
|
|
#include "gl/GrGLDefines.h"
|
|
|
|
#include "gl/GrGLInterface.h"
|
|
|
|
#include "SkApplication.h"
|
2013-07-24 17:48:03 +00:00
|
|
|
#include "SkCommandLineFlags.h"
|
2013-06-18 15:37:27 +00:00
|
|
|
#include "SkGpuDevice.h"
|
|
|
|
#include "SkGraphics.h"
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \
|
|
|
|
"Multiple matches may be separated by spaces.\n" \
|
|
|
|
"~ causes a matching test to always be skipped\n" \
|
|
|
|
"^ requires the start of the test to match\n" \
|
|
|
|
"$ requires the end of the test to match\n" \
|
|
|
|
"^ and $ requires an exact match\n" \
|
|
|
|
"If a test does not match any list entry,\n" \
|
|
|
|
"it is skipped unless some list entry starts with ~");
|
|
|
|
|
2013-06-18 15:37:27 +00:00
|
|
|
void application_init() {
|
|
|
|
SkGraphics::Init();
|
|
|
|
SkEvent::Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void application_term() {
|
|
|
|
SkEvent::Term();
|
|
|
|
SkGraphics::Term();
|
|
|
|
}
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
SkExampleWindow::SkExampleWindow(void* hwnd)
|
|
|
|
: INHERITED(hwnd) {
|
|
|
|
fRegistry = SkExample::Registry::Head();
|
|
|
|
fCurrExample = fRegistry->factory()(this);
|
|
|
|
|
|
|
|
if (FLAGS_match.count()) {
|
|
|
|
// Start with the a matching sample if possible.
|
|
|
|
bool found = this->findNextMatch();
|
|
|
|
if (!found) {
|
|
|
|
SkDebugf("No matching SkExample found.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-06-18 15:37:27 +00:00
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
void SkExampleWindow::tearDownBackend() {
|
2013-06-18 15:37:27 +00:00
|
|
|
if (kGPU_DeviceType == fType) {
|
|
|
|
SkSafeUnref(fContext);
|
|
|
|
fContext = NULL;
|
|
|
|
|
|
|
|
SkSafeUnref(fInterface);
|
|
|
|
fInterface = NULL;
|
|
|
|
|
|
|
|
SkSafeUnref(fRenderTarget);
|
|
|
|
fRenderTarget = NULL;
|
|
|
|
|
|
|
|
detach();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
bool SkExampleWindow::setupBackend(DeviceType type) {
|
2013-06-18 15:37:27 +00:00
|
|
|
fType = type;
|
|
|
|
|
2014-03-07 13:24:52 +00:00
|
|
|
this->setColorType(kRGBA_8888_SkColorType);
|
2013-06-18 15:37:27 +00:00
|
|
|
this->setVisibleP(true);
|
|
|
|
this->setClipToBounds(false);
|
|
|
|
|
|
|
|
bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo);
|
|
|
|
if (false == result) {
|
|
|
|
SkDebugf("Not possible to create backend.\n");
|
|
|
|
detach();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fInterface = GrGLCreateNativeInterface();
|
|
|
|
|
|
|
|
SkASSERT(NULL != fInterface);
|
|
|
|
|
|
|
|
fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface);
|
|
|
|
SkASSERT(NULL != fContext);
|
|
|
|
|
|
|
|
setupRenderTarget();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
void SkExampleWindow::setupRenderTarget() {
|
2013-06-18 15:37:27 +00:00
|
|
|
GrBackendRenderTargetDesc desc;
|
2013-12-17 19:22:07 +00:00
|
|
|
desc.fWidth = SkScalarRoundToInt(width());
|
|
|
|
desc.fHeight = SkScalarRoundToInt(height());
|
2013-06-18 15:37:27 +00:00
|
|
|
desc.fConfig = kSkia8888_GrPixelConfig;
|
|
|
|
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
|
|
|
desc.fSampleCnt = fAttachmentInfo.fSampleCount;
|
|
|
|
desc.fStencilBits = fAttachmentInfo.fStencilBits;
|
|
|
|
|
|
|
|
GrGLint buffer;
|
|
|
|
GR_GL_GetIntegerv(fInterface, GR_GL_FRAMEBUFFER_BINDING, &buffer);
|
|
|
|
desc.fRenderTargetHandle = buffer;
|
|
|
|
|
|
|
|
fRenderTarget = fContext->wrapBackendRenderTarget(desc);
|
|
|
|
|
|
|
|
fContext->setRenderTarget(fRenderTarget);
|
|
|
|
}
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
SkCanvas* SkExampleWindow::createCanvas() {
|
2013-06-18 15:37:27 +00:00
|
|
|
if (fType == kGPU_DeviceType) {
|
|
|
|
if (NULL != fContext && NULL != fRenderTarget) {
|
2013-08-29 11:54:56 +00:00
|
|
|
SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(fContext, fRenderTarget));
|
2013-06-18 15:37:27 +00:00
|
|
|
return new SkCanvas(device);
|
|
|
|
}
|
|
|
|
tearDownBackend();
|
|
|
|
setupBackend(kRaster_DeviceType);
|
|
|
|
}
|
|
|
|
return INHERITED::createCanvas();
|
|
|
|
}
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
void SkExampleWindow::draw(SkCanvas* canvas) {
|
|
|
|
if (NULL != fCurrExample) {
|
|
|
|
fCurrExample->draw(canvas);
|
|
|
|
}
|
2013-06-18 15:37:27 +00:00
|
|
|
if (fType == kGPU_DeviceType) {
|
|
|
|
|
|
|
|
SkASSERT(NULL != fContext);
|
|
|
|
fContext->flush();
|
|
|
|
}
|
|
|
|
if (fType == kRaster_DeviceType) {
|
|
|
|
// need to send the raster bits to the (gpu) window
|
|
|
|
fContext->setRenderTarget(fRenderTarget);
|
|
|
|
const SkBitmap& bm = getBitmap();
|
|
|
|
fRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
|
|
|
|
kSkia8888_GrPixelConfig,
|
|
|
|
bm.getPixels(),
|
|
|
|
bm.rowBytes());
|
|
|
|
}
|
|
|
|
INHERITED::present();
|
|
|
|
}
|
|
|
|
|
2013-07-24 17:48:03 +00:00
|
|
|
void SkExampleWindow::onSizeChange() {
|
2013-06-18 15:37:27 +00:00
|
|
|
setupRenderTarget();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SK_BUILD_FOR_WIN
|
2013-07-24 17:48:03 +00:00
|
|
|
void SkExampleWindow::onHandleInval(const SkIRect& rect) {
|
2013-06-19 07:01:12 +00:00
|
|
|
RECT winRect;
|
|
|
|
winRect.top = rect.top();
|
|
|
|
winRect.bottom = rect.bottom();
|
|
|
|
winRect.right = rect.right();
|
|
|
|
winRect.left = rect.left();
|
|
|
|
InvalidateRect((HWND)this->getHWND(), &winRect, false);
|
2013-06-18 15:37:27 +00:00
|
|
|
}
|
|
|
|
#endif
|
2013-07-24 17:48:03 +00:00
|
|
|
|
|
|
|
bool SkExampleWindow::findNextMatch() {
|
|
|
|
bool found = false;
|
|
|
|
// Avoid infinite loop by knowing where we started.
|
|
|
|
const SkExample::Registry* begin = fRegistry;
|
|
|
|
while (!found) {
|
|
|
|
fRegistry = fRegistry->next();
|
|
|
|
if (NULL == fRegistry) { // Reached the end of the registered samples. GOTO head.
|
|
|
|
fRegistry = SkExample::Registry::Head();
|
|
|
|
}
|
|
|
|
SkExample* next = fRegistry->factory()(this);
|
2013-08-30 15:52:46 +00:00
|
|
|
if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, next->getName().c_str())) {
|
2013-07-24 17:48:03 +00:00
|
|
|
fCurrExample = next;
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
if (begin == fRegistry) { // We looped through every sample without finding anything.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SkExampleWindow::onHandleChar(SkUnichar unichar) {
|
|
|
|
if ('n' == unichar) {
|
|
|
|
bool found = findNextMatch();
|
|
|
|
if (!found) {
|
|
|
|
SkDebugf("No SkExample that matches your query\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
|
|
|
|
SkCommandLineFlags::Parse(argc, argv);
|
|
|
|
return new SkExampleWindow(hwnd);
|
|
|
|
}
|