• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/html/canvas/WebGLProgram.h"
29 
30 #include "core/html/canvas/WebGLRenderingContextBase.h"
31 
32 namespace WebCore {
33 
create(WebGLRenderingContextBase * ctx)34 PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContextBase* ctx)
35 {
36     return adoptRef(new WebGLProgram(ctx));
37 }
38 
WebGLProgram(WebGLRenderingContextBase * ctx)39 WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
40     : WebGLSharedObject(ctx)
41     , m_linkStatus(false)
42     , m_linkCount(0)
43     , m_infoValid(true)
44 {
45     ScriptWrappable::init(this);
46     setObject(ctx->webContext()->createProgram());
47 }
48 
~WebGLProgram()49 WebGLProgram::~WebGLProgram()
50 {
51     deleteObject(0);
52 }
53 
deleteObjectImpl(blink::WebGraphicsContext3D * context3d,Platform3DObject obj)54 void WebGLProgram::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject obj)
55 {
56     context3d->deleteProgram(obj);
57     if (m_vertexShader) {
58         m_vertexShader->onDetached(context3d);
59         m_vertexShader = nullptr;
60     }
61     if (m_fragmentShader) {
62         m_fragmentShader->onDetached(context3d);
63         m_fragmentShader = nullptr;
64     }
65 }
66 
numActiveAttribLocations()67 unsigned WebGLProgram::numActiveAttribLocations()
68 {
69     cacheInfoIfNeeded();
70     return m_activeAttribLocations.size();
71 }
72 
getActiveAttribLocation(GLuint index)73 GLint WebGLProgram::getActiveAttribLocation(GLuint index)
74 {
75     cacheInfoIfNeeded();
76     if (index >= numActiveAttribLocations())
77         return -1;
78     return m_activeAttribLocations[index];
79 }
80 
isUsingVertexAttrib0()81 bool WebGLProgram::isUsingVertexAttrib0()
82 {
83     cacheInfoIfNeeded();
84     for (unsigned ii = 0; ii < numActiveAttribLocations(); ++ii) {
85         if (!getActiveAttribLocation(ii))
86             return true;
87     }
88     return false;
89 }
90 
linkStatus()91 bool WebGLProgram::linkStatus()
92 {
93     cacheInfoIfNeeded();
94     return m_linkStatus;
95 }
96 
increaseLinkCount()97 void WebGLProgram::increaseLinkCount()
98 {
99     ++m_linkCount;
100     m_infoValid = false;
101 }
102 
getAttachedShader(GLenum type)103 WebGLShader* WebGLProgram::getAttachedShader(GLenum type)
104 {
105     switch (type) {
106     case GL_VERTEX_SHADER:
107         return m_vertexShader.get();
108     case GL_FRAGMENT_SHADER:
109         return m_fragmentShader.get();
110     default:
111         return 0;
112     }
113 }
114 
attachShader(WebGLShader * shader)115 bool WebGLProgram::attachShader(WebGLShader* shader)
116 {
117     if (!shader || !shader->object())
118         return false;
119     switch (shader->type()) {
120     case GL_VERTEX_SHADER:
121         if (m_vertexShader)
122             return false;
123         m_vertexShader = shader;
124         return true;
125     case GL_FRAGMENT_SHADER:
126         if (m_fragmentShader)
127             return false;
128         m_fragmentShader = shader;
129         return true;
130     default:
131         return false;
132     }
133 }
134 
detachShader(WebGLShader * shader)135 bool WebGLProgram::detachShader(WebGLShader* shader)
136 {
137     if (!shader || !shader->object())
138         return false;
139     switch (shader->type()) {
140     case GL_VERTEX_SHADER:
141         if (m_vertexShader != shader)
142             return false;
143         m_vertexShader = nullptr;
144         return true;
145     case GL_FRAGMENT_SHADER:
146         if (m_fragmentShader != shader)
147             return false;
148         m_fragmentShader = nullptr;
149         return true;
150     default:
151         return false;
152     }
153 }
154 
cacheActiveAttribLocations(blink::WebGraphicsContext3D * context3d)155 void WebGLProgram::cacheActiveAttribLocations(blink::WebGraphicsContext3D* context3d)
156 {
157     m_activeAttribLocations.clear();
158 
159     GLint numAttribs = 0;
160     context3d->getProgramiv(object(), GL_ACTIVE_ATTRIBUTES, &numAttribs);
161     m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
162     for (int i = 0; i < numAttribs; ++i) {
163         blink::WebGraphicsContext3D::ActiveInfo info;
164         context3d->getActiveAttrib(object(), i, info);
165         m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.utf8().data());
166     }
167 }
168 
cacheInfoIfNeeded()169 void WebGLProgram::cacheInfoIfNeeded()
170 {
171     if (m_infoValid)
172         return;
173 
174     if (!object())
175         return;
176 
177     blink::WebGraphicsContext3D* context = getAWebGraphicsContext3D();
178     if (!context)
179         return;
180     GLint linkStatus = 0;
181     context->getProgramiv(object(), GL_LINK_STATUS, &linkStatus);
182     m_linkStatus = linkStatus;
183     if (m_linkStatus)
184         cacheActiveAttribLocations(context);
185     m_infoValid = true;
186 }
187 
188 }
189