1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #if ENABLE(WEBGL)
29
30 #include "WebGLProgram.h"
31
32 #include "WebGLRenderingContext.h"
33
34 namespace WebCore {
35
create(WebGLRenderingContext * ctx)36 PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
37 {
38 return adoptRef(new WebGLProgram(ctx));
39 }
40
WebGLProgram(WebGLRenderingContext * ctx)41 WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
42 : WebGLObject(ctx)
43 , m_linkStatus(false)
44 , m_linkCount(0)
45 {
46 setObject(context()->graphicsContext3D()->createProgram());
47 }
48
deleteObjectImpl(Platform3DObject obj)49 void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
50 {
51 context()->graphicsContext3D()->deleteProgram(obj);
52 if (m_vertexShader) {
53 m_vertexShader->onDetached();
54 m_vertexShader = 0;
55 }
56 if (m_fragmentShader) {
57 m_fragmentShader->onDetached();
58 m_fragmentShader = 0;
59 }
60 }
61
cacheActiveAttribLocations()62 bool WebGLProgram::cacheActiveAttribLocations()
63 {
64 m_activeAttribLocations.clear();
65 if (!object())
66 return false;
67 GraphicsContext3D* context3d = context()->graphicsContext3D();
68
69 // Assume link status has already been cached.
70 if (!m_linkStatus)
71 return false;
72
73 GC3Dint numAttribs = 0;
74 context3d->getProgramiv(object(), GraphicsContext3D::ACTIVE_ATTRIBUTES, &numAttribs);
75 m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
76 for (int i = 0; i < numAttribs; ++i) {
77 ActiveInfo info;
78 context3d->getActiveAttrib(object(), i, info);
79 m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.charactersWithNullTermination());
80 }
81
82 return true;
83 }
84
numActiveAttribLocations() const85 unsigned WebGLProgram::numActiveAttribLocations() const
86 {
87 return m_activeAttribLocations.size();
88 }
89
getActiveAttribLocation(GC3Duint index) const90 GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index) const
91 {
92 if (index >= numActiveAttribLocations())
93 return -1;
94 return m_activeAttribLocations[index];
95 }
96
isUsingVertexAttrib0() const97 bool WebGLProgram::isUsingVertexAttrib0() const
98 {
99 for (unsigned ii = 0; ii < numActiveAttribLocations(); ++ii) {
100 if (!getActiveAttribLocation(ii))
101 return true;
102 }
103 return false;
104 }
105
getAttachedShader(GC3Denum type)106 WebGLShader* WebGLProgram::getAttachedShader(GC3Denum type)
107 {
108 switch (type) {
109 case GraphicsContext3D::VERTEX_SHADER:
110 return m_vertexShader.get();
111 case GraphicsContext3D::FRAGMENT_SHADER:
112 return m_fragmentShader.get();
113 default:
114 return 0;
115 }
116 }
117
attachShader(WebGLShader * shader)118 bool WebGLProgram::attachShader(WebGLShader* shader)
119 {
120 if (!shader || !shader->object())
121 return false;
122 switch (shader->getType()) {
123 case GraphicsContext3D::VERTEX_SHADER:
124 if (m_vertexShader)
125 return false;
126 m_vertexShader = shader;
127 return true;
128 case GraphicsContext3D::FRAGMENT_SHADER:
129 if (m_fragmentShader)
130 return false;
131 m_fragmentShader = shader;
132 return true;
133 default:
134 return false;
135 }
136 }
137
detachShader(WebGLShader * shader)138 bool WebGLProgram::detachShader(WebGLShader* shader)
139 {
140 if (!shader || !shader->object())
141 return false;
142 switch (shader->getType()) {
143 case GraphicsContext3D::VERTEX_SHADER:
144 if (m_vertexShader != shader)
145 return false;
146 m_vertexShader = 0;
147 return true;
148 case GraphicsContext3D::FRAGMENT_SHADER:
149 if (m_fragmentShader != shader)
150 return false;
151 m_fragmentShader = 0;
152 return true;
153 default:
154 return false;
155 }
156 }
157
158 }
159
160 #endif // ENABLE(WEBGL)
161