1//
2// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
8
9#include "libGLESv2/main.h"
10#include "libGLESv2/Program.h"
11#include "libGLESv2/renderer/Renderer.h"
12#include "common/utilities.h"
13#include "third_party/trace_event/trace_event.h"
14#include "libGLESv2/Shader.h"
15
16#if defined (ANGLE_ENABLE_D3D9)
17#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
18#endif // ANGLE_ENABLE_D3D9
19
20#if defined (ANGLE_ENABLE_D3D11)
21#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
22#endif // ANGLE_ENABLE_D3D11
23
24#if !defined(ANGLE_DEFAULT_D3D11)
25// Enables use of the Direct3D 11 API for a default display, when available
26#define ANGLE_DEFAULT_D3D11 0
27#endif
28
29#include <EGL/eglext.h>
30
31namespace rx
32{
33
34Renderer::Renderer(egl::Display *display)
35    : mDisplay(display),
36      mCapsInitialized(false),
37      mCurrentClientVersion(2)
38{
39}
40
41Renderer::~Renderer()
42{
43}
44
45const gl::Caps &Renderer::getRendererCaps() const
46{
47    if (!mCapsInitialized)
48    {
49        generateCaps(&mCaps, &mTextureCaps, &mExtensions);
50        mCapsInitialized = true;
51    }
52
53    return mCaps;
54}
55
56const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const
57{
58    if (!mCapsInitialized)
59    {
60        generateCaps(&mCaps, &mTextureCaps, &mExtensions);
61        mCapsInitialized = true;
62    }
63
64    return mTextureCaps;
65}
66
67const gl::Extensions &Renderer::getRendererExtensions() const
68{
69    if (!mCapsInitialized)
70    {
71        generateCaps(&mCaps, &mTextureCaps, &mExtensions);
72        mCapsInitialized = true;
73    }
74
75    return mExtensions;
76}
77
78typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, EGLint);
79
80template <typename RendererType>
81Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType)
82{
83    return new RendererType(display, nativeDisplay, requestedDisplayType);
84}
85
86}
87
88extern "C"
89{
90
91rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, EGLint requestedDisplayType)
92{
93    std::vector<rx::CreateRendererFunction> rendererCreationFunctions;
94
95#   if defined(ANGLE_ENABLE_D3D11)
96        if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
97            nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
98            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
99            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE)
100        {
101            rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
102        }
103#   endif
104
105#   if defined(ANGLE_ENABLE_D3D9)
106        if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
107            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
108        {
109            rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
110        }
111#   endif
112
113    if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE &&
114        nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE &&
115        requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
116    {
117        // The default display is requested, try the D3D9 and D3D11 renderers, order them using
118        // the definition of ANGLE_DEFAULT_D3D11
119#       if ANGLE_DEFAULT_D3D11
120#           if defined(ANGLE_ENABLE_D3D11)
121                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
122#           endif
123#           if defined(ANGLE_ENABLE_D3D9)
124                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
125#           endif
126#       else
127#           if defined(ANGLE_ENABLE_D3D9)
128                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
129#           endif
130#           if defined(ANGLE_ENABLE_D3D11)
131                rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
132#           endif
133#       endif
134    }
135
136    for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
137    {
138        rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, requestedDisplayType);
139        if (renderer->initialize() == EGL_SUCCESS)
140        {
141            return renderer;
142        }
143        else
144        {
145            // Failed to create the renderer, try the next
146            SafeDelete(renderer);
147        }
148    }
149
150    return NULL;
151}
152
153void glDestroyRenderer(rx::Renderer *renderer)
154{
155    delete renderer;
156}
157
158}
159