Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region License
2
//
3
// The Open Toolkit Library License
4
//
5
// Copyright (c) 2006 - 2009 the Open Toolkit library.
6
//
7
// Permission is hereby granted, free of charge, to any person obtaining a copy
8
// of this software and associated documentation files (the "Software"), to deal
9
// in the Software without restriction, including without limitation the rights to 
10
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
// the Software, and to permit persons to whom the Software is furnished to do
12
// so, subject to the following conditions:
13
//
14
// The above copyright notice and this permission notice shall be included in all
15
// copies or substantial portions of the Software.
16
//
17
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
// OTHER DEALINGS IN THE SOFTWARE.
25
//
26
#endregion
27
 
28
using System;
29
 
30
using OpenTK.Graphics;
31
using System.Diagnostics;
32
using OpenTK.Platform.Windows;
33
 
34
namespace OpenTK.Platform.Egl
35
{
36
    class EglContext : EmbeddedGraphicsContext
37
    {
38
        #region Fields
39
 
40
        EglWindowInfo WindowInfo;
41
        IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } }
42
        bool vsync = true;   // Default vsync value is defined as 1 (true) in EGL.
43
 
44
        #endregion
45
 
46
        #region Constructors
47
 
48
        public EglContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
49
            int major, int minor, GraphicsContextFlags flags)
50
        {
51
            if (mode == null)
52
                throw new ArgumentNullException("mode");
53
            if (window == null)
54
                throw new ArgumentNullException("window");
55
 
56
            EglContext shared = (EglContext)sharedContext;
57
 
58
            int dummy_major, dummy_minor;
59
            if (!Egl.Initialize(window.Display, out dummy_major, out dummy_minor))
60
                throw new GraphicsContextException(String.Format("Failed to initialize EGL, error {0}.", Egl.GetError()));
61
 
62
            WindowInfo = window;
63
 
64
            Mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
65
            if (!Mode.Index.HasValue)
66
                throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
67
            IntPtr config = Mode.Index.Value;
68
 
69
            if (window.Surface == IntPtr.Zero)
70
                window.CreateWindowSurface(config);
71
 
72
            int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
73
            HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : IntPtr.Zero, attrib_list);
74
 
75
            MakeCurrent(window);
76
        }
77
 
78
        public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
79
            int major, int minor, GraphicsContextFlags flags)
80
        {
81
            if (handle == ContextHandle.Zero)
82
                throw new ArgumentException("handle");
83
            if (window == null)
84
                throw new ArgumentNullException("window");
85
 
86
            Handle = handle;
87
        }
88
 
89
        #endregion
90
 
91
        #region IGraphicsContext Members
92
 
93
        public override void SwapBuffers()
94
        {
95
            Egl.SwapBuffers(WindowInfo.Display, WindowInfo.Surface);
96
        }
97
 
98
        public override void MakeCurrent(IWindowInfo window)
99
        {
100
            // Ignore 'window', unless it actually is an EGL window. In other words,
101
            // trying to make the EglContext current on a non-EGL window will do,
102
            // nothing (the EglContext will remain current on the previous EGL window
103
            // or the window it was constructed on (which may not be EGL)).
104
            if (window is EglWindowInfo)
105
                WindowInfo = (EglWindowInfo)window;
106
            Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, HandleAsEGLContext);
107
        }
108
 
109
        public override bool IsCurrent
110
        {
111
            get { return Egl.GetCurrentContext() == HandleAsEGLContext; }
112
        }
113
 
114
        public override bool VSync
115
        {
116
            get
117
            {
118
                // Egl.GetSwapInterval does not exist, so store and return the current interval.
119
                // The default interval is defined as 1 (true).
120
                return vsync;
121
            }
122
            set
123
            {
124
                if (Egl.SwapInterval(WindowInfo.Display, value ? 1 : 0))
125
                    vsync = value;
126
                else
127
                    Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", WindowInfo.Display, value);
128
            }
129
        }
130
 
131
        #endregion
132
 
133
        #region IGraphicsContextInternal Members
134
 
135
        public override IntPtr GetAddress(string function)
136
        {
137
            return Egl.GetProcAddress(function);
138
        }
139
 
140
        #endregion
141
 
142
        #region IDisposable Members
143
 
144
        public override void Dispose()
145
        {
146
            Dispose(true);
147
            GC.SuppressFinalize(this);
148
        }
149
 
150
        // Todo: cross-reference the specs. What should happen if the context is destroyed from a different
151
        // thread?
152
        void Dispose(bool manual)
153
        {
154
            if (!IsDisposed)
155
            {
156
                if (manual)
157
                {
158
                    Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, IntPtr.Zero);
159
                    Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext);
160
                }
161
                else
162
                {
163
                    Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, HandleAsEGLContext);
164
                }
165
                IsDisposed = true;
166
            }
167
        }
168
 
169
        ~EglContext()
170
        {
171
            Dispose(false);
172
        }
173
 
174
        #endregion
175
    }
176
}