1/*
2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#ifndef SurfaceOpenVG_h
21#define SurfaceOpenVG_h
22
23#if PLATFORM(EGL)
24#include <egl.h>
25#endif
26
27#include <wtf/Noncopyable.h>
28#include <wtf/Platform.h>
29
30namespace WebCore {
31
32#if PLATFORM(EGL)
33class EGLDisplayOpenVG;
34#endif
35class PainterOpenVG;
36class IntSize;
37
38/**
39 * SurfaceOpenVG provides the functionality of surfaces and contexts that are
40 * underlying the OpenVG implementation. In the vast majority of cases, that
41 * underlying technology is EGL, but OpenVG doesn't depend on EGL per se.
42 * Wrapping surface/context functionality into a separate class avoids lots
43 * of #ifdefs and should make it easy to add different surface/context
44 * implementations than EGL.
45 */
46class SurfaceOpenVG : public Noncopyable {
47public:
48    enum MakeCurrentMode {
49        ApplyPainterStateOnSurfaceSwitch,
50        DontApplyPainterState,
51    };
52
53    static SurfaceOpenVG* currentSurface();
54
55#if PLATFORM(EGL)
56    friend class EGLDisplayOpenVG;
57
58    /**
59     * Create a new EGL pbuffer surface with the specified size and config on
60     * the given display. If config is not specified, the display's default
61     * pbuffer config is used.
62     *
63     * This constructor will trigger an assertion if creation of the surface
64     * fails, unless you pledge to manually process the error code by passing
65     * a non-zero pointer as errorCode parameter. The error code returned by
66     * eglGetError() will be written to that variable.
67     */
68    SurfaceOpenVG(const IntSize& size, const EGLDisplay& display, EGLConfig* config = 0, EGLint* errorCode = 0);
69
70    /**
71     * Create a new EGL window surface with the specified native window handle
72     * and config on the given display. If config is not specified, the
73     * display's default window config is used.
74     */
75    SurfaceOpenVG(EGLNativeWindowType window, const EGLDisplay& display, EGLConfig* config = 0);
76
77    EGLDisplay eglDisplay() const { return m_eglDisplay; }
78    EGLSurface eglSurface() const { return m_eglSurface; }
79    EGLContext eglContext() const { return m_eglContext; }
80#endif
81
82    ~SurfaceOpenVG();
83
84    /**
85     * If a surface is invalid (could not be created), all method calls will
86     * crash horribly.
87     */
88    bool isValid() const;
89
90    int width() const;
91    int height() const;
92
93    SurfaceOpenVG* sharedSurface() const;
94
95    /**
96     * Make the associated GL/EGL context the current one, so that subsequent
97     * OpenVG commands apply to it.
98     */
99    void makeCurrent(MakeCurrentMode mode = ApplyPainterStateOnSurfaceSwitch);
100
101    /**
102     * Make a surface/context combination current that is "compatible"
103     * (i.e. can access its shared resources) to the given one. If no
104     * surface/context is current, the given one is made current.
105     *
106     * This method is meant to avoid context changes if they're not
107     * necessary, particularly tailored for the case where something
108     * compatible to the shared surface is requested while actual painting
109     * happens on another surface.
110     */
111    void makeCompatibleCurrent();
112
113    /**
114     * Empty the OpenVG pipeline and make sure all the performed paint
115     * operations show up on the surface as actual drawn pixels.
116     */
117    void flush();
118
119    void setActivePainter(PainterOpenVG*);
120    PainterOpenVG* activePainter();
121
122private:
123    PainterOpenVG* m_activePainter;
124    static PainterOpenVG* s_currentPainter; // global currently active painter
125
126#if PLATFORM(EGL)
127    SurfaceOpenVG(); // for EGLDisplayOpenVG
128
129    EGLDisplay m_eglDisplay;
130    EGLSurface m_eglSurface;
131    EGLContext m_eglContext;
132#endif
133};
134
135}
136
137#endif
138