1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef APP_SURFACE_ACCELERATED_SURFACE_MAC_H_
#define APP_SURFACE_ACCELERATED_SURFACE_MAC_H_
#include <CoreFoundation/CoreFoundation.h>
#include <OpenGL/OpenGL.h>
#include "app/surface/transport_dib.h"
#include "base/callback.h"
#include "base/scoped_cftyperef.h"
#include "base/scoped_ptr.h"
#include "gfx/rect.h"
#include "gfx/size.h"
namespace gfx {
class Rect;
}
// Encapsulates an accelerated GL surface that can be shared across processes
// on systems that support it (10.6 and above). For systems that do not, it
// uses a regular dib. There will either be a GL Context or a TransportDIB,
// never both.
class AcceleratedSurface {
public:
AcceleratedSurface();
virtual ~AcceleratedSurface() { }
// Set up internal buffers. Returns false upon failure.
bool Initialize();
// Tear down. Must be called before destructor to prevent leaks.
void Destroy();
// These methods are used only when there is a GL surface.
// Sets the accelerated surface to the given size, creating a new one if
// the height or width changes. Returns a unique id of the IOSurface to
// which the surface is bound, or 0 if no changes were made or an error
// occurred. MakeCurrent() will have been called on the new surface.
uint64 SetSurfaceSize(const gfx::Size& size);
// Sets the GL context to be the current one for drawing. Returns true if
// it succeeded.
bool MakeCurrent();
// Clear the surface to all white. Assumes the caller has already called
// MakeCurrent().
void Clear(const gfx::Rect& rect);
// Call after making changes to the surface which require a visual update.
// Makes the rendering show up in other processes.
void SwapBuffers();
CGLContextObj context() { return gl_context_; }
// These methods are only used when there is a transport DIB.
// Sets the transport DIB to the given size, creating a new one if the
// height or width changes. Returns a handle to the new DIB, or a default
// handle if no changes were made.
TransportDIB::Handle SetTransportDIBSize(const gfx::Size& size);
// Sets the methods to use for allocating and freeing memory for the
// transport DIB.
void SetTransportDIBAllocAndFree(
Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
Callback1<TransportDIB::Id>::Type* deallocator);
// Get the accelerated surface size.
gfx::Size GetSize() const { return surface_size_; }
private:
// Helper function to generate names for the backing texture, render buffers
// and FBO. On return, the resulting buffer names can be attached to |fbo_|.
// |target| is the target type for the color buffer.
void AllocateRenderBuffers(GLenum target, const gfx::Size& size);
// Helper function to attach the buffers previously allocated by a call to
// AllocateRenderBuffers(). On return, |fbo_| can be used for
// rendering. |target| must be the same value as used in the call to
// AllocateRenderBuffers(). Returns |true| if the resulting framebuffer
// object is valid.
bool SetupFrameBufferObject(GLenum target);
CGLContextObj gl_context_;
CGLPBufferObj pbuffer_;
// Either |io_surface_| or |transport_dib_| is a valid pointer, but not both.
// |io_surface_| is non-NULL if the IOSurface APIs are supported (Mac OS X
// 10.6 and later).
// TODO(dspringer,kbr): Should the GPU backing store be encapsulated in its
// own class so all this implementation detail is hidden?
scoped_cftyperef<CFTypeRef> io_surface_;
// TODO(dspringer): If we end up keeping this TransportDIB mechanism, this
// should really be a scoped_ptr_malloc<>, with a deallocate functor that
// runs |dib_free_callback_|. I was not able to figure out how to
// make this work (or even compile).
scoped_ptr<TransportDIB> transport_dib_;
gfx::Size surface_size_;
GLuint texture_;
GLuint fbo_;
GLuint depth_stencil_renderbuffer_;
// For tracking whether the default framebuffer / renderbuffer or
// ones created by the end user are currently bound
// TODO(kbr): Need to property hook up and track the OpenGL state and hook
// up the notion of the currently bound FBO.
GLuint bound_fbo_;
GLuint bound_renderbuffer_;
// Allocate a TransportDIB in the renderer.
scoped_ptr<Callback2<size_t, TransportDIB::Handle*>::Type>
dib_alloc_callback_;
scoped_ptr<Callback1<TransportDIB::Id>::Type> dib_free_callback_;
};
#endif // APP_SURFACE_ACCELERATED_SURFACE_MAC_H_
|