17361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com/* 27361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * Copyright 2012 Google Inc. 37361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * 47361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 57361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * found in the LICENSE file. 67361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com */ 77361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 87361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#ifndef GrContextFactory_DEFINED 97361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#define GrContextFactory_DEFINED 107361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 117361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#if SK_ANGLE 127361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com #include "gl/SkANGLEGLContext.h" 137361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 147361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#include "gl/SkDebugGLContext.h" 157361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#if SK_MESA 167361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com #include "gl/SkMesaGLContext.h" 177361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 187361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#include "gl/SkNativeGLContext.h" 197361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#include "gl/SkNullGLContext.h" 207361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 217361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#include "GrContext.h" 22a2d71482db8b6d752a51c96da74768d7dfc27932robertphillips@google.com#include "SkTArray.h" 237361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 247361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com/** 25fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * This is a simple class that is useful in test apps that use different 267361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * GrContexts backed by different types of GL contexts. It manages creating the 277361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * GL context and a GrContext that uses it. The GL/Gr contexts persist until the 287361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com * factory is destroyed (though the caller can always grab a ref on the returned 29d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org * Gr and GL contexts to make them outlive the factory). 307361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com */ 31e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.orgclass GrContextFactory : SkNoncopyable { 327361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.compublic: 337361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com /** 34d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org * Types of GL contexts supported. For historical and testing reasons the native GrContext will 35d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org * not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context 36d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org * type that does not remove NVPR support and which will fail when the driver does not support 37d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org * the extension. 387361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com */ 397361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com enum GLContextType { 407361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com kNative_GLContextType, 417361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#if SK_ANGLE 427361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com kANGLE_GLContextType, 437361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 447361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#if SK_MESA 457361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com kMESA_GLContextType, 467361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 47d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org /** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not 48d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org support NVPR */ 49d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org kNVPR_GLContextType, 507361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com kNull_GLContextType, 517361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com kDebug_GLContextType, 5267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 5367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com kLastGLContextType = kDebug_GLContextType 547361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com }; 557361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 5667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com static const int kGLContextTypeCnt = kLastGLContextType + 1; 5767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 5867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com static bool IsRenderingGLContext(GLContextType type) { 5967b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com switch (type) { 6067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com case kNull_GLContextType: 6167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com case kDebug_GLContextType: 6267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com return false; 6367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com default: 6467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com return true; 6567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 6667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 6767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 68cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com static const char* GLContextTypeName(GLContextType type) { 69cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com switch (type) { 70cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com case kNative_GLContextType: 71cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com return "native"; 72cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com case kNull_GLContextType: 73cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com return "null"; 74cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_ANGLE 75cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com case kANGLE_GLContextType: 76cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com return "angle"; 77cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif 78cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_MESA 79cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com case kMESA_GLContextType: 80cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com return "mesa"; 81cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif 82d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org case kNVPR_GLContextType: 83d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org return "nvpr"; 84cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com case kDebug_GLContextType: 85cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com return "debug"; 86cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com default: 8788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown GL Context type."); 88cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com } 89cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com } 90cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com 917361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com GrContextFactory() { 927361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 937361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 9467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com ~GrContextFactory() { this->destroyContexts(); } 9567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 9667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com void destroyContexts() { 977361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com for (int i = 0; i < fContexts.count(); ++i) { 98d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org fContexts[i].fGLContext->makeCurrent(); 997361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com fContexts[i].fGrContext->unref(); 1007361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com fContexts[i].fGLContext->unref(); 1017361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 10267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com fContexts.reset(); 1037361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1047361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 1057361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com /** 10667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com * Get a GrContext initialized with a type of GL context. It also makes the GL context current. 1077361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com */ 1087361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com GrContext* get(GLContextType type) { 1097361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 1107361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com for (int i = 0; i < fContexts.count(); ++i) { 1117361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com if (fContexts[i].fType == type) { 11267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com fContexts[i].fGLContext->makeCurrent(); 1137361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com return fContexts[i].fGrContext; 1147361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1157361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1166177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com SkAutoTUnref<SkGLContextHelper> glCtx; 1177361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com SkAutoTUnref<GrContext> grCtx; 1187361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com switch (type) { 119d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org case kNVPR_GLContextType: // fallthru 1207361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com case kNative_GLContextType: 121c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com glCtx.reset(SkNEW(SkNativeGLContext)); 1227361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com break; 1237361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#ifdef SK_ANGLE 1247361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com case kANGLE_GLContextType: 125c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com glCtx.reset(SkNEW(SkANGLEGLContext)); 1267361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com break; 1277361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 1287361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#ifdef SK_MESA 1297361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com case kMESA_GLContextType: 130c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com glCtx.reset(SkNEW(SkMesaGLContext)); 1317361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com break; 1327361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 1337361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com case kNull_GLContextType: 134c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com glCtx.reset(SkNEW(SkNullGLContext)); 1357361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com break; 1367361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com case kDebug_GLContextType: 137c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com glCtx.reset(SkNEW(SkDebugGLContext)); 1387361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com break; 1397361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1407361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com static const int kBogusSize = 1; 1417361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com if (!glCtx.get()) { 1427361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com return NULL; 1437361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1447361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com if (!glCtx.get()->init(kBogusSize, kBogusSize)) { 1457361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com return NULL; 1467361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 147d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org 148d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org // Ensure NVPR is available for the NVPR type and block it from other types. 149d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx.get()->gl())); 150d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org if (kNVPR_GLContextType == type) { 151d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org if (!glInterface->hasExtension("GL_NV_path_rendering")) { 152d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org return NULL; 153d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org } 154d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org } else { 155d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface)); 156d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org if (!glInterface) { 157d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org return NULL; 158d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org } 159d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org } 160d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org 161d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org glCtx->makeCurrent(); 162d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get()); 16316e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx)); 1647361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com if (!grCtx.get()) { 1657361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com return NULL; 1667361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1677361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com GPUContext& ctx = fContexts.push_back(); 1687361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com ctx.fGLContext = glCtx.get(); 1697361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com ctx.fGLContext->ref(); 1707361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com ctx.fGrContext = grCtx.get(); 1717361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com ctx.fGrContext->ref(); 1727361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com ctx.fType = type; 1737361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com return ctx.fGrContext; 1747361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com } 1755bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org 1765bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org // Returns the GLContext of the given type. If it has not been created yet, 1775bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org // NULL is returned instead. 1786177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com SkGLContextHelper* getGLContext(GLContextType type) { 1795bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org for (int i = 0; i < fContexts.count(); ++i) { 1805bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org if (fContexts[i].fType == type) { 1815bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org return fContexts[i].fGLContext; 1825bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org } 1835bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org } 1845bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org 1855bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org return NULL; 1865bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org } 1875bdef29ae0f5a495381cd2c9787ce7c112e58354keyar@chromium.org 1887361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.comprivate: 1897361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com struct GPUContext { 1907361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com GLContextType fType; 1916177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com SkGLContextHelper* fGLContext; 1927361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com GrContext* fGrContext; 1937361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com }; 1947361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com SkTArray<GPUContext, true> fContexts; 1957361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com}; 1967361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com 1977361f54294d65a5c42ce5cf1cd56d0fd7122e268bsalomon@google.com#endif 198