Home | History | Annotate | Download | only in canvas
      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 
     36 PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
     37 {
     38     return adoptRef(new WebGLProgram(ctx));
     39 }
     40 
     41 WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
     42     : WebGLObject(ctx)
     43     , m_linkStatus(false)
     44     , m_linkCount(0)
     45 {
     46     setObject(context()->graphicsContext3D()->createProgram());
     47 }
     48 
     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 
     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 
     85 unsigned WebGLProgram::numActiveAttribLocations() const
     86 {
     87     return m_activeAttribLocations.size();
     88 }
     89 
     90 GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index) const
     91 {
     92     if (index >= numActiveAttribLocations())
     93         return -1;
     94     return m_activeAttribLocations[index];
     95 }
     96 
     97 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 
    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 
    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 
    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