bool
WebGLContext::ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer,
                                      const char* info)
{
    if (!buffer)
        return true;

    /* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1
     *
     * In the WebGL 2 API, buffers have their WebGL buffer type
     * initially set to undefined. Calling bindBuffer, bindBufferRange
     * or bindBufferBase with the target argument set to any buffer
     * binding point except COPY_READ_BUFFER or COPY_WRITE_BUFFER will
     * then set the WebGL buffer type of the buffer being bound
     * according to the table above.
     *
     * Any call to one of these functions which attempts to bind a
     * WebGLBuffer that has the element array WebGL buffer type to a
     * binding point that falls under other data, or bind a
     * WebGLBuffer which has the other data WebGL buffer type to
     * ELEMENT_ARRAY_BUFFER will generate an INVALID_OPERATION error,
     * and the state of the binding point will remain untouched.
     */

    GLenum boundTo = GetCurrentBinding(buffer);
    if (boundTo != LOCAL_GL_NONE) {
        if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
            boundTo != LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER)
        {
            ErrorInvalidOperation("Can't bind buffer to TRANSFORM_FEEDBACK_BUFFER as the "
                                  "buffer is already bound to another bind point.");
            return false;
        }
        else if (target != LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER &&
                 boundTo == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER)
        {
            ErrorInvalidOperation("Can't bind buffer to bind point as it is currently "
                                  "bound to TRANSFORM_FEEDBACK_BUFFER.");
            return false;
        }
    }

    WebGLBuffer::Kind content = buffer->Content();
    if (content == WebGLBuffer::Kind::Undefined)
        return true;

    switch (target) {
    case LOCAL_GL_COPY_READ_BUFFER:
    case LOCAL_GL_COPY_WRITE_BUFFER:
        return true;

    case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
        if (content == WebGLBuffer::Kind::ElementArray)
            return true;
        break;

    case LOCAL_GL_ARRAY_BUFFER:
    case LOCAL_GL_PIXEL_PACK_BUFFER:
    case LOCAL_GL_PIXEL_UNPACK_BUFFER:
    case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
    case LOCAL_GL_UNIFORM_BUFFER:
        if (content == WebGLBuffer::Kind::OtherData)
            return true;
        break;

    default:
        MOZ_CRASH();
    }

    ErrorInvalidOperation("%s: buffer already contains %s data.", info,
                          content == WebGLBuffer::Kind::OtherData ? "other" : "element");

    return false;
}
Example #2
0
struct ISAPNPBase* ASMCALL
initRoutine( REG( d0, struct ISAPNPBase* res ),
             REG( a0, APTR                    seglist ),
             REG( a6, struct ExecBase*        sysbase ) )
{
  SysBase = sysbase;

  if( ! OpenLibs() )
  {
    // No libraries?

    Req( "Failed to open required libraries." );
  }
  else
  {
    ULONG                 actual;
    struct CurrentBinding current_binding;

    actual = GetCurrentBinding( &current_binding, 
                                sizeof( current_binding ) );

    if( actual < sizeof( current_binding ) )
    {
      // No legal CurrentBinding structure

      Req( "No legal CurrentBinding structure found." );

    }
    else
    {
      struct ConfigDev* cd = current_binding.cb_ConfigDev;

      if( cd == NULL )
      {
        // No card found

        Req( "No bridge card found." );
      }
      else
      {
        if( cd->cd_Rom.er_Manufacturer != 2150 ||
            cd->cd_Rom.er_Product      != 1 )
        {
          // Unsupported ISA bridge

          Req( "Unsupported ISA bridge: %ld/%ld.\n"
               "Only the GG2 Bus+ card is supported.", 
               cd->cd_Rom.er_Manufacturer, 
               cd->cd_Rom.er_Product );
        }
        else
        {
          if( cd->cd_BoardAddr == NULL )
          {
            // No board address?

            Req( "No board address?" );
          }
          else
          {
            // Set up the ISAPNPBase structure

            res->m_Library.lib_Node.ln_Type = NT_RESOURCE;
            res->m_Library.lib_Node.ln_Name = (STRPTR) ResName;
            res->m_Library.lib_Flags        = LIBF_SUMUSED | LIBF_CHANGED;
            res->m_Library.lib_Version      = VERSION;
            res->m_Library.lib_Revision     = REVISION;
            res->m_Library.lib_IdString     = (STRPTR) IDString;

            NewList( &res->m_Cards );

            res->m_Base        = cd->cd_BoardAddr;
            res->m_RegReadData = 0x0000;

            res->m_ConfigDev   = cd;

            if( ! ISAPNP_ScanCards( res ) )
            {
              // No cards found

              Req( "No PnP ISA cards found." );
              FreeISAPNPBase( res );
            }
            else
            {
              struct ISAPNP_Card* card;

              card = ISAPNP_AllocCard( res );

              if( card == NULL )
              {
                Req( "Out of memory!" );
                FreeISAPNPBase( res );
              }
              else
              {
                static const char descr[] = "Non-PnP devices";
                char*             d;                
                
                d = AllocVec( sizeof( descr ), MEMF_PUBLIC );
                
                if( d != NULL )
                {
                  CopyMem( (void*) descr, d, sizeof( descr ) );
                  card->isapnpc_Node.ln_Name = d;
                }

                card->isapnpc_ID.isapnpid_Vendor[ 0 ] = '?';
                card->isapnpc_ID.isapnpid_Vendor[ 1 ] = '?';
                card->isapnpc_ID.isapnpid_Vendor[ 2 ] = '?';
                card->isapnpc_SerialNumber = -1;

                // Add *first*
                AddHead( &res->m_Cards, (struct Node*) card );

                // Let's see if we're to disable any cards or devices etc

                if( ! HandleToolTypes( current_binding.cb_ToolTypes, 
                                       card, res ) )
                {
                  // Error requester already displayed.
                  FreeISAPNPBase( res );
                }
                else
                {
                  if( ! ISAPNP_ConfigureCards( res ) )
                  {
                    // Unable to configure cards

                    Req( "Unable to configure the cards. This is most likely\n"
                         "because of an unresolvable hardware conflict.\n\n"
                         "Use the DISABLE_DEVICE tool type to disable one of\n"
                         "the devices in conflict." );
                    FreeISAPNPBase( res );
                  }
                  else
                  {
                    cd->cd_Flags  &= ~CDF_CONFIGME;
                    cd->cd_Driver  = res;

                    ISAPNPBase = res;
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  return ISAPNPBase;
}