mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Pull WebGL conformance 2.0.0 suite
This commit is contained in:
parent
90f657757f
commit
07094641f2
4646 changed files with 564933 additions and 0 deletions
|
@ -0,0 +1,7 @@
|
|||
// files that end in .txt list other tests
|
||||
// other lines are assumed to be .html files
|
||||
|
||||
conformance/00_test_list.txt
|
||||
conformance/more/00_test_list.txt
|
||||
deqp/00_test_list.txt
|
||||
--min-version 2.0.0 conformance2/00_test_list.txt
|
|
@ -0,0 +1,127 @@
|
|||
Rules for Claiming a Conformant WebGL Implementation
|
||||
====================================================
|
||||
|
||||
The WebGL API is a web standard, and many web browser implementers
|
||||
deliver their browser on multiple operating systems (OSs). WebGL
|
||||
implementations also typically rely on the presence of an OpenGL or
|
||||
OpenGL ES implementation on the OS. It can be appreciated that a WebGL
|
||||
implementation therefore has many dependencies. This document attempts
|
||||
to clarify to potential implementers the rules the Khronos Group uses
|
||||
to judge whether a particular WebGL implementation is conformant.
|
||||
|
||||
There are two primary reasons to submit conformance results:
|
||||
|
||||
A) A web browser implementer desires to certify their WebGL
|
||||
implementation as conformant.
|
||||
|
||||
B) A GPU manufacturer delivering an embedded system including web
|
||||
browser with WebGL support desires to certify their WebGL
|
||||
implementation as conformant.
|
||||
|
||||
Each of these situations carries different constraints, so the
|
||||
conformance rules are phrased differently for each. Typically, a web
|
||||
browser implementer aims to certify that the WebGL "layer" is correct.
|
||||
A GPU vendor typically aims to certify that a given device is
|
||||
physically capable of passing the tests.
|
||||
|
||||
A newly-developed WebGL implementation should not support the "webgl"
|
||||
HTML Canvas context type by default in a shipping version of the
|
||||
product until reaching conformance. It is acceptable to give end users
|
||||
an option to turn on WebGL support in a non-conformant implementation
|
||||
as long as the documentation for that option clearly indicates that
|
||||
the implementation is not yet conformant and may have compatibility
|
||||
issues. It is suggested that the Canvas context type
|
||||
"experimental-webgl" may be supported by default in such
|
||||
implementations.
|
||||
|
||||
A WebGL implementation might reach conformance, but a subsequent
|
||||
graphics driver release on a particular OS might introduce a
|
||||
regression causing failures of one or more of the WebGL conformance
|
||||
tests. In this situation it is not required to revoke support for the
|
||||
"webgl" HTML Canvas context type. The WebGL implementer should work
|
||||
with the GPU vendor to ensure the driver regression is fixed. A
|
||||
situation like this would, however, prevent the WebGL implementer from
|
||||
conforming to a subsequent version of the test suite.
|
||||
|
||||
(A) Conformance Rules for a Web Browser Implementer
|
||||
===================================================
|
||||
|
||||
1. Conformance on a particular operating system
|
||||
|
||||
On a given OS, a WebGL implementation will be considered to conform to
|
||||
a particular version of the conformance suite if the suite passes with
|
||||
no test failures on at least two GPUs, each from a different
|
||||
vendor. If the OS only supports a GPU from one vendor, the two-GPU
|
||||
requirement is dropped.
|
||||
|
||||
2. Conformance across multiple operating systems
|
||||
|
||||
A WebGL implementation will be considered to conform to a particular
|
||||
version of the conformance suite if it passes rule (1) on all of the
|
||||
OSs on which the WebGL implementation is intended to be supported.
|
||||
|
||||
3. Conformance as the web browser is upgraded
|
||||
|
||||
WebGL conformance results submitted for an earlier version of the
|
||||
browser carry forward to later versions of the browser that do not
|
||||
cause any previously passing test to fail.
|
||||
|
||||
4. Conformance as the operating system is upgraded
|
||||
|
||||
If a new version is released of one of the OSs on which a WebGL
|
||||
implementation is intended to run, then WebGL conformance results
|
||||
submitted for earlier versions of that OS carry forward. Future
|
||||
conformance results must be submitted against the new version of the
|
||||
OS. If it is anticipated that the older OS version will be supported
|
||||
for some time, then future conformance results must be submitted
|
||||
separately for both the old and new versions of the OS.
|
||||
|
||||
(B) Conformance Rules for a GPU Vendor
|
||||
======================================
|
||||
|
||||
A GPU vendor submitting conformance results for a WebGL implementation
|
||||
typically does so because the device containing the GPU includes a
|
||||
built-in web browser. In this case the following rules apply:
|
||||
|
||||
1. Conformance results must be submitted for each GPU and operating
|
||||
system combination to be certified. It is not required to submit
|
||||
results for different devices containing the same GPU and running the
|
||||
same operating system that do not cause any previously passing test to
|
||||
fail.
|
||||
|
||||
2. Conformance results carry forward for a given GPU as the operating
|
||||
system and graphics driver are upgraded but do not cause any previously
|
||||
passing test to fail.
|
||||
|
||||
Discussion
|
||||
==========
|
||||
|
||||
A WebGL implementation intended to ship on three OSs may reach
|
||||
conformance on two of them, but due to graphics driver bugs, may be
|
||||
unable to reach conformance on the third. In this situation the
|
||||
implementation is not yet considered to be conformant.
|
||||
|
||||
An existing WebGL implementation which conformed to an earlier version
|
||||
of the test suite is not required to remove support for the "webgl"
|
||||
HTML Canvas context type while in the process of conforming to a later
|
||||
version of the test suite. However, the implementer must not advertise
|
||||
conformance to the later version until it has been reached. It is
|
||||
acceptable for the implementer to advertise details of their
|
||||
conformance, for example number or percentage of passing or failing
|
||||
tests, or names of passing or failing tests.
|
||||
|
||||
A GPU vendor might submit conformance results in order to use the
|
||||
WebGL logo in a marketing campaign. In this situation, results may be
|
||||
submitted in advance of the product becoming available through sales
|
||||
channels, per the rules above.
|
||||
|
||||
The WebGL API has strict security requirements. Even one failing test
|
||||
may indicate a serious security issue in the WebGL implementation. For
|
||||
this reason, no exceptions for failing conformance tests will be
|
||||
granted.
|
||||
|
||||
The Khronos Group determines whether a particular WebGL implementation
|
||||
is conformant based on the implementer's conformance suite
|
||||
submissions, on multiple OSs and on multiple GPUs as necessary, using
|
||||
the rules above. An implementer shall not judge their own
|
||||
implementation conformant simply by applying the above rules.
|
79
tests/wpt/mozilla/tests/webgl/conformance-2.0.0/README.md
Normal file
79
tests/wpt/mozilla/tests/webgl/conformance-2.0.0/README.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
Welcome to the WebGL Conformance Test Suite
|
||||
===========================================
|
||||
|
||||
Note: Before adding a new test or editing an existing test
|
||||
[please read these guidelines](test-guidelines.md).
|
||||
|
||||
This is the WebGL conformance test suite. You can find a the current "live"
|
||||
version at [https://www.khronos.org/registry/webgl/sdk/tests/webgl-conformance-tests.html](https://www.khronos.org/registry/webgl/sdk/tests/webgl-conformance-tests.html)
|
||||
|
||||
NOTE TO USERS: Unless you are a WebGL implementor, there is no need to submit
|
||||
a conformance result using this process. Should you discover bugs in your
|
||||
browser's WebGL implementation, either via this test suite or otherwise,
|
||||
please report them through your browser vendor's bug tracking system.
|
||||
|
||||
FOR WEBGL IMPLEMENTORS: Please follow the instructions below to create
|
||||
a formal conformance submission.
|
||||
|
||||
1. Open webgl-conformance-tests.html in your target browser
|
||||
|
||||
2. Press the "run tests" button
|
||||
|
||||
3. At the end of the run, press "display text summary"
|
||||
|
||||
4. Verify that the User Agent and WebGL renderer strings identify your browser and target correctly.
|
||||
|
||||
5. Copy the contents of the text summary (starting with "WebGL Conformance Test Results") and send via email to
|
||||
webgl_conformance_submissions@khronos.org
|
||||
|
||||
Please see CONFORMANCE_RULES.txt in this directory for guidelines
|
||||
about what constitutes a conformant WebGL implementation.
|
||||
|
||||
Usage Notes:
|
||||
------------
|
||||
|
||||
There are various URL options you can pass in.
|
||||
|
||||
run: Set to 1 to start the tests automatically
|
||||
|
||||
Example: webgl-conformance-tests.html?run=1
|
||||
|
||||
version: Set to the version of the harness you wish to run. Tests
|
||||
at this version or below will be run
|
||||
|
||||
Example: webgl-conformance-tests.html?version=1.3.2
|
||||
|
||||
minVersion: Set to the minimum version of each test to include. Only tests
|
||||
at this version or above will be included.
|
||||
|
||||
Example: webgl-conformance-tests.html?minVersion=1.3.2
|
||||
|
||||
fast: Only run tests not marked with --slow
|
||||
|
||||
Example: webgl-conformance-tests.html?fast=true
|
||||
|
||||
skip: Comma separated list of regular expressions of which tests to skip.
|
||||
|
||||
Example: webgl-conformance-tests.html?skip=glsl,.*destruction\.html
|
||||
|
||||
include: Comma separated list of regular expressions of which tests to include.
|
||||
|
||||
Example: webgl-conformance-tests.html?include=glsl,.*destruction\.html
|
||||
|
||||
frames: The number of iframes to use to run tests in parallel.
|
||||
|
||||
Example: webgl-conformance-tests.html?frames=8
|
||||
|
||||
Note the tests are not required to run with anything other than frames = 1.
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
The dates below are when work on the conformance suite version was started.
|
||||
|
||||
- 2011/02/24: Version 1.0.0
|
||||
- 2012/02/23: Version 1.0.1
|
||||
- 2012/03/20: Version 1.0.2
|
||||
- 2013/02/14: Version 1.0.3
|
||||
- 2013/10/11: Version 2.0.0 (beta)
|
||||
- 2014/11/14: Version 1.0.4
|
|
@ -0,0 +1,19 @@
|
|||
# This is a list of contributors to the Closure Library.
|
||||
|
||||
# Names should be added to this file like so:
|
||||
# Name or Organization <email address>
|
||||
|
||||
Google Inc.
|
||||
Stellar Science Ltd.
|
||||
Mohamed Mansour <hello@mohamedmansour.com>
|
||||
Bjorn Tipling <bjorn.tipling@gmail.com>
|
||||
SameGoal LLC <help@samegoal.com>
|
||||
Guido Tapia <guido.tapia@gmail.com>
|
||||
Andrew Mattie <amattie@gmail.com>
|
||||
Ilia Mirkin <ibmirkin@gmail.com>
|
||||
Ivan Kozik <ivan.kozik@gmail.com>
|
||||
Rich Dougherty <rich@rd.gen.nz>
|
||||
Chad Killingsworth <chadkillingsworth@missouristate.edu>
|
||||
Dan Pupius <dan.pupius@gmail.com>
|
||||
Mike Dunn <dunn74@gmail.com>
|
||||
Kengo Toda <skypencil@gmail.com>
|
|
@ -0,0 +1,48 @@
|
|||
Closure Library welcomes patches/pulls for features and bugfixes.
|
||||
|
||||
For contributors inside Google, follow the instructions given here:
|
||||
http://go/closure-contributors
|
||||
|
||||
For contributors external to Google, follow the instructions given here:
|
||||
|
||||
Notes on Contributions to Closure Library
|
||||
|
||||
Google Individual Contributor License
|
||||
|
||||
In all cases, contributors must sign a contributor license agreement,
|
||||
either for an individual or corporation, before a patch can be
|
||||
accepted. Please fill out the agreement for an individual or a
|
||||
corporation, as appropriate.
|
||||
|
||||
https://developers.google.com/open-source/cla/individual
|
||||
https://developers.google.com/open-source/cla/corporate
|
||||
|
||||
If you or your organization is not listed there already, you should
|
||||
add an entry to the AUTHORS file as part of your patch.
|
||||
|
||||
If you plan to add a significant component or large chunk of code, it
|
||||
is recommended to bring it up on the discussion list for a design
|
||||
discussion before writing code.
|
||||
|
||||
If appropriate, write a unit test that demonstrates your patch. Tests are the
|
||||
best way to ensure that future contributors do not break your code
|
||||
accidentally.
|
||||
|
||||
To change the Closure Library source, you must submit a pull request
|
||||
in GitHub. See the GitHub documentation here:
|
||||
|
||||
https://help.github.com/categories/63/articles
|
||||
|
||||
Closure Library developers monitor outstanding pull requests. They may
|
||||
request changes on the pull request before accepting. They will also
|
||||
verify that the CLA has been signed.
|
||||
|
||||
Oftentimes, the pull request will not be directly merged, but patched to
|
||||
the internal Google codebase to verify that unit and integration tests
|
||||
will Closure pass before submitting (and optionally make changes to
|
||||
the patch to match style, fix text, or to make the code or comments
|
||||
clearer). In this case, the issue associated with the pull request
|
||||
will be closed when the patch pushed to the repository via the MOE
|
||||
(Make Open Easy) system.
|
||||
|
||||
https://code.google.com/p/moe-java/
|
|
@ -0,0 +1,176 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -0,0 +1,20 @@
|
|||
This is a partial snapshot of the Closure library workspace from:
|
||||
|
||||
https://github.com/google/closure-library
|
||||
|
||||
It contains only the portions needed to type check the ported dEQP
|
||||
tests, namely:
|
||||
|
||||
closure/goog/base.js
|
||||
closure/goog/deps.js
|
||||
|
||||
and supporting scripts in closure/bin/ .
|
||||
|
||||
The current version snapshotted here is:
|
||||
|
||||
-----
|
||||
commit 57bdfe0093cc158fb3a58d2c5f7d75ece8c4b45b
|
||||
Author: Nathan Naze <nanaze@gmail.com>
|
||||
Date: Fri Apr 24 18:38:26 2015 -0400
|
||||
|
||||
fix bad merge
|
|
@ -0,0 +1,9 @@
|
|||
# Closure Library
|
||||
|
||||
Closure Library is a powerful, low-level JavaScript library designed
|
||||
for building complex and scalable web applications. It is used by many
|
||||
Google web applications, such as Gmail and Google Docs.
|
||||
|
||||
For more information, visit the
|
||||
[Google Developers](https://developers.google.com/closure/library) or
|
||||
[GitHub](https://github.com/google/closure-library) sites.
|
|
@ -0,0 +1,287 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Utility for Closure Library dependency calculation.
|
||||
|
||||
ClosureBuilder scans source files to build dependency info. From the
|
||||
dependencies, the script can produce a manifest in dependency order,
|
||||
a concatenated script, or compiled output from the Closure Compiler.
|
||||
|
||||
Paths to files can be expressed as individual arguments to the tool (intended
|
||||
for use with find and xargs). As a convenience, --root can be used to specify
|
||||
all JS files below a directory.
|
||||
|
||||
usage: %prog [options] [file1.js file2.js ...]
|
||||
"""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import depstree
|
||||
import jscompiler
|
||||
import source
|
||||
import treescan
|
||||
|
||||
|
||||
def _GetOptionsParser():
|
||||
"""Get the options parser."""
|
||||
|
||||
parser = optparse.OptionParser(__doc__)
|
||||
parser.add_option('-i',
|
||||
'--input',
|
||||
dest='inputs',
|
||||
action='append',
|
||||
default=[],
|
||||
help='One or more input files to calculate dependencies '
|
||||
'for. The namespaces in this file will be combined with '
|
||||
'those given with the -n flag to form the set of '
|
||||
'namespaces to find dependencies for.')
|
||||
parser.add_option('-n',
|
||||
'--namespace',
|
||||
dest='namespaces',
|
||||
action='append',
|
||||
default=[],
|
||||
help='One or more namespaces to calculate dependencies '
|
||||
'for. These namespaces will be combined with those given '
|
||||
'with the -i flag to form the set of namespaces to find '
|
||||
'dependencies for. A Closure namespace is a '
|
||||
'dot-delimited path expression declared with a call to '
|
||||
'goog.provide() (e.g. "goog.array" or "foo.bar").')
|
||||
parser.add_option('--root',
|
||||
dest='roots',
|
||||
action='append',
|
||||
default=[],
|
||||
help='The paths that should be traversed to build the '
|
||||
'dependencies.')
|
||||
parser.add_option('-o',
|
||||
'--output_mode',
|
||||
dest='output_mode',
|
||||
type='choice',
|
||||
action='store',
|
||||
choices=['list', 'script', 'compiled'],
|
||||
default='list',
|
||||
help='The type of output to generate from this script. '
|
||||
'Options are "list" for a list of filenames, "script" '
|
||||
'for a single script containing the contents of all the '
|
||||
'files, or "compiled" to produce compiled output with '
|
||||
'the Closure Compiler. Default is "list".')
|
||||
parser.add_option('-c',
|
||||
'--compiler_jar',
|
||||
dest='compiler_jar',
|
||||
action='store',
|
||||
help='The location of the Closure compiler .jar file.')
|
||||
parser.add_option('-f',
|
||||
'--compiler_flags',
|
||||
dest='compiler_flags',
|
||||
default=[],
|
||||
action='append',
|
||||
help='Additional flags to pass to the Closure compiler. '
|
||||
'To pass multiple flags, --compiler_flags has to be '
|
||||
'specified multiple times.')
|
||||
parser.add_option('-j',
|
||||
'--jvm_flags',
|
||||
dest='jvm_flags',
|
||||
default=[],
|
||||
action='append',
|
||||
help='Additional flags to pass to the JVM compiler. '
|
||||
'To pass multiple flags, --jvm_flags has to be '
|
||||
'specified multiple times.')
|
||||
parser.add_option('--output_file',
|
||||
dest='output_file',
|
||||
action='store',
|
||||
help=('If specified, write output to this path instead of '
|
||||
'writing to standard output.'))
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def _GetInputByPath(path, sources):
|
||||
"""Get the source identified by a path.
|
||||
|
||||
Args:
|
||||
path: str, A path to a file that identifies a source.
|
||||
sources: An iterable collection of source objects.
|
||||
|
||||
Returns:
|
||||
The source from sources identified by path, if found. Converts to
|
||||
real paths for comparison.
|
||||
"""
|
||||
for js_source in sources:
|
||||
# Convert both to real paths for comparison.
|
||||
if os.path.realpath(path) == os.path.realpath(js_source.GetPath()):
|
||||
return js_source
|
||||
|
||||
|
||||
def _GetClosureBaseFile(sources):
|
||||
"""Given a set of sources, returns the one base.js file.
|
||||
|
||||
Note that if zero or two or more base.js files are found, an error message
|
||||
will be written and the program will be exited.
|
||||
|
||||
Args:
|
||||
sources: An iterable of _PathSource objects.
|
||||
|
||||
Returns:
|
||||
The _PathSource representing the base Closure file.
|
||||
"""
|
||||
base_files = [
|
||||
js_source for js_source in sources if _IsClosureBaseFile(js_source)]
|
||||
|
||||
if not base_files:
|
||||
logging.error('No Closure base.js file found.')
|
||||
sys.exit(1)
|
||||
if len(base_files) > 1:
|
||||
logging.error('More than one Closure base.js files found at these paths:')
|
||||
for base_file in base_files:
|
||||
logging.error(base_file.GetPath())
|
||||
sys.exit(1)
|
||||
return base_files[0]
|
||||
|
||||
|
||||
def _IsClosureBaseFile(js_source):
|
||||
"""Returns true if the given _PathSource is the Closure base.js source."""
|
||||
return (os.path.basename(js_source.GetPath()) == 'base.js' and
|
||||
js_source.provides == set(['goog']))
|
||||
|
||||
|
||||
class _PathSource(source.Source):
|
||||
"""Source file subclass that remembers its file path."""
|
||||
|
||||
def __init__(self, path):
|
||||
"""Initialize a source.
|
||||
|
||||
Args:
|
||||
path: str, Path to a JavaScript file. The source string will be read
|
||||
from this file.
|
||||
"""
|
||||
super(_PathSource, self).__init__(source.GetFileContents(path))
|
||||
|
||||
self._path = path
|
||||
|
||||
def __str__(self):
|
||||
return 'PathSource %s' % self._path
|
||||
|
||||
def GetPath(self):
|
||||
"""Returns the path."""
|
||||
return self._path
|
||||
|
||||
|
||||
def _WrapGoogModuleSource(src):
|
||||
return ('goog.loadModule(function(exports) {{'
|
||||
'"use strict";'
|
||||
'{0}'
|
||||
'\n' # terminate any trailing single line comment.
|
||||
';return exports'
|
||||
'}});\n').format(src)
|
||||
|
||||
|
||||
def main():
|
||||
logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
|
||||
level=logging.INFO)
|
||||
options, args = _GetOptionsParser().parse_args()
|
||||
|
||||
# Make our output pipe.
|
||||
if options.output_file:
|
||||
out = open(options.output_file, 'w')
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
sources = set()
|
||||
|
||||
logging.info('Scanning paths...')
|
||||
for path in options.roots:
|
||||
for js_path in treescan.ScanTreeForJsFiles(path):
|
||||
sources.add(_PathSource(js_path))
|
||||
|
||||
# Add scripts specified on the command line.
|
||||
for js_path in args:
|
||||
sources.add(_PathSource(js_path))
|
||||
|
||||
logging.info('%s sources scanned.', len(sources))
|
||||
|
||||
# Though deps output doesn't need to query the tree, we still build it
|
||||
# to validate dependencies.
|
||||
logging.info('Building dependency tree..')
|
||||
tree = depstree.DepsTree(sources)
|
||||
|
||||
input_namespaces = set()
|
||||
inputs = options.inputs or []
|
||||
for input_path in inputs:
|
||||
js_input = _GetInputByPath(input_path, sources)
|
||||
if not js_input:
|
||||
logging.error('No source matched input %s', input_path)
|
||||
sys.exit(1)
|
||||
input_namespaces.update(js_input.provides)
|
||||
|
||||
input_namespaces.update(options.namespaces)
|
||||
|
||||
if not input_namespaces:
|
||||
logging.error('No namespaces found. At least one namespace must be '
|
||||
'specified with the --namespace or --input flags.')
|
||||
sys.exit(2)
|
||||
|
||||
# The Closure Library base file must go first.
|
||||
base = _GetClosureBaseFile(sources)
|
||||
deps = [base] + tree.GetDependencies(input_namespaces)
|
||||
|
||||
output_mode = options.output_mode
|
||||
if output_mode == 'list':
|
||||
out.writelines([js_source.GetPath() + '\n' for js_source in deps])
|
||||
elif output_mode == 'script':
|
||||
for js_source in deps:
|
||||
src = js_source.GetSource()
|
||||
if js_source.is_goog_module:
|
||||
src = _WrapGoogModuleSource(src)
|
||||
out.write(src + '\n')
|
||||
elif output_mode == 'compiled':
|
||||
logging.warning("""\
|
||||
Closure Compiler now natively understands and orders Closure dependencies and
|
||||
is prefererred over using this script for performing JavaScript compilation.
|
||||
|
||||
Please migrate your codebase.
|
||||
|
||||
See:
|
||||
https://github.com/google/closure-compiler/wiki/Manage-Closure-Dependencies
|
||||
""")
|
||||
|
||||
# Make sure a .jar is specified.
|
||||
if not options.compiler_jar:
|
||||
logging.error('--compiler_jar flag must be specified if --output is '
|
||||
'"compiled"')
|
||||
sys.exit(2)
|
||||
|
||||
# Will throw an error if the compilation fails.
|
||||
compiled_source = jscompiler.Compile(
|
||||
options.compiler_jar,
|
||||
[js_source.GetPath() for js_source in deps],
|
||||
jvm_flags=options.jvm_flags,
|
||||
compiler_flags=options.compiler_flags)
|
||||
|
||||
logging.info('JavaScript compilation succeeded.')
|
||||
out.write(compiled_source)
|
||||
|
||||
else:
|
||||
logging.error('Invalid value for --output flag.')
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,189 @@
|
|||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Class to represent a full Closure Library dependency tree.
|
||||
|
||||
Offers a queryable tree of dependencies of a given set of sources. The tree
|
||||
will also do logical validation to prevent duplicate provides and circular
|
||||
dependencies.
|
||||
"""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
class DepsTree(object):
|
||||
"""Represents the set of dependencies between source files."""
|
||||
|
||||
def __init__(self, sources):
|
||||
"""Initializes the tree with a set of sources.
|
||||
|
||||
Args:
|
||||
sources: A set of JavaScript sources.
|
||||
|
||||
Raises:
|
||||
MultipleProvideError: A namespace is provided by muplitple sources.
|
||||
NamespaceNotFoundError: A namespace is required but never provided.
|
||||
"""
|
||||
|
||||
self._sources = sources
|
||||
self._provides_map = dict()
|
||||
|
||||
# Ensure nothing was provided twice.
|
||||
for source in sources:
|
||||
for provide in source.provides:
|
||||
if provide in self._provides_map:
|
||||
raise MultipleProvideError(
|
||||
provide, [self._provides_map[provide], source])
|
||||
|
||||
self._provides_map[provide] = source
|
||||
|
||||
# Check that all required namespaces are provided.
|
||||
for source in sources:
|
||||
for require in source.requires:
|
||||
if require not in self._provides_map:
|
||||
raise NamespaceNotFoundError(require, source)
|
||||
|
||||
def GetDependencies(self, required_namespaces):
|
||||
"""Get source dependencies, in order, for the given namespaces.
|
||||
|
||||
Args:
|
||||
required_namespaces: A string (for one) or list (for one or more) of
|
||||
namespaces.
|
||||
|
||||
Returns:
|
||||
A list of source objects that provide those namespaces and all
|
||||
requirements, in dependency order.
|
||||
|
||||
Raises:
|
||||
NamespaceNotFoundError: A namespace is requested but doesn't exist.
|
||||
CircularDependencyError: A cycle is detected in the dependency tree.
|
||||
"""
|
||||
if isinstance(required_namespaces, str):
|
||||
required_namespaces = [required_namespaces]
|
||||
|
||||
deps_sources = []
|
||||
|
||||
for namespace in required_namespaces:
|
||||
for source in DepsTree._ResolveDependencies(
|
||||
namespace, [], self._provides_map, []):
|
||||
if source not in deps_sources:
|
||||
deps_sources.append(source)
|
||||
|
||||
return deps_sources
|
||||
|
||||
@staticmethod
|
||||
def _ResolveDependencies(required_namespace, deps_list, provides_map,
|
||||
traversal_path):
|
||||
"""Resolve dependencies for Closure source files.
|
||||
|
||||
Follows the dependency tree down and builds a list of sources in dependency
|
||||
order. This function will recursively call itself to fill all dependencies
|
||||
below the requested namespaces, and then append its sources at the end of
|
||||
the list.
|
||||
|
||||
Args:
|
||||
required_namespace: String of required namespace.
|
||||
deps_list: List of sources in dependency order. This function will append
|
||||
the required source once all of its dependencies are satisfied.
|
||||
provides_map: Map from namespace to source that provides it.
|
||||
traversal_path: List of namespaces of our path from the root down the
|
||||
dependency/recursion tree. Used to identify cyclical dependencies.
|
||||
This is a list used as a stack -- when the function is entered, the
|
||||
current namespace is pushed and popped right before returning.
|
||||
Each recursive call will check that the current namespace does not
|
||||
appear in the list, throwing a CircularDependencyError if it does.
|
||||
|
||||
Returns:
|
||||
The given deps_list object filled with sources in dependency order.
|
||||
|
||||
Raises:
|
||||
NamespaceNotFoundError: A namespace is requested but doesn't exist.
|
||||
CircularDependencyError: A cycle is detected in the dependency tree.
|
||||
"""
|
||||
|
||||
source = provides_map.get(required_namespace)
|
||||
if not source:
|
||||
raise NamespaceNotFoundError(required_namespace)
|
||||
|
||||
if required_namespace in traversal_path:
|
||||
traversal_path.append(required_namespace) # do this *after* the test
|
||||
|
||||
# This must be a cycle.
|
||||
raise CircularDependencyError(traversal_path)
|
||||
|
||||
# If we don't have the source yet, we'll have to visit this namespace and
|
||||
# add the required dependencies to deps_list.
|
||||
if source not in deps_list:
|
||||
traversal_path.append(required_namespace)
|
||||
|
||||
for require in source.requires:
|
||||
|
||||
# Append all other dependencies before we append our own.
|
||||
DepsTree._ResolveDependencies(require, deps_list, provides_map,
|
||||
traversal_path)
|
||||
deps_list.append(source)
|
||||
|
||||
traversal_path.pop()
|
||||
|
||||
return deps_list
|
||||
|
||||
|
||||
class BaseDepsTreeError(Exception):
|
||||
"""Base DepsTree error."""
|
||||
|
||||
def __init__(self):
|
||||
Exception.__init__(self)
|
||||
|
||||
|
||||
class CircularDependencyError(BaseDepsTreeError):
|
||||
"""Raised when a dependency cycle is encountered."""
|
||||
|
||||
def __init__(self, dependency_list):
|
||||
BaseDepsTreeError.__init__(self)
|
||||
self._dependency_list = dependency_list
|
||||
|
||||
def __str__(self):
|
||||
return ('Encountered circular dependency:\n%s\n' %
|
||||
'\n'.join(self._dependency_list))
|
||||
|
||||
|
||||
class MultipleProvideError(BaseDepsTreeError):
|
||||
"""Raised when a namespace is provided more than once."""
|
||||
|
||||
def __init__(self, namespace, sources):
|
||||
BaseDepsTreeError.__init__(self)
|
||||
self._namespace = namespace
|
||||
self._sources = sources
|
||||
|
||||
def __str__(self):
|
||||
source_strs = map(str, self._sources)
|
||||
|
||||
return ('Namespace "%s" provided more than once in sources:\n%s\n' %
|
||||
(self._namespace, '\n'.join(source_strs)))
|
||||
|
||||
|
||||
class NamespaceNotFoundError(BaseDepsTreeError):
|
||||
"""Raised when a namespace is requested but not provided."""
|
||||
|
||||
def __init__(self, namespace, source=None):
|
||||
BaseDepsTreeError.__init__(self)
|
||||
self._namespace = namespace
|
||||
self._source = source
|
||||
|
||||
def __str__(self):
|
||||
msg = 'Namespace "%s" never provided.' % self._namespace
|
||||
if self._source:
|
||||
msg += ' Required in %s' % self._source
|
||||
return msg
|
|
@ -0,0 +1,204 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Generates out a Closure deps.js file given a list of JavaScript sources.
|
||||
|
||||
Paths can be specified as arguments or (more commonly) specifying trees
|
||||
with the flags (call with --help for descriptions).
|
||||
|
||||
Usage: depswriter.py [path/to/js1.js [path/to/js2.js] ...]
|
||||
"""
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import posixpath
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
import source
|
||||
import treescan
|
||||
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
def MakeDepsFile(source_map):
|
||||
"""Make a generated deps file.
|
||||
|
||||
Args:
|
||||
source_map: A dict map of the source path to source.Source object.
|
||||
|
||||
Returns:
|
||||
str, A generated deps file source.
|
||||
"""
|
||||
|
||||
# Write in path alphabetical order
|
||||
paths = sorted(source_map.keys())
|
||||
|
||||
lines = []
|
||||
|
||||
for path in paths:
|
||||
js_source = source_map[path]
|
||||
|
||||
# We don't need to add entries that don't provide anything.
|
||||
if js_source.provides:
|
||||
lines.append(_GetDepsLine(path, js_source))
|
||||
|
||||
return ''.join(lines)
|
||||
|
||||
|
||||
def _GetDepsLine(path, js_source):
|
||||
"""Get a deps.js file string for a source."""
|
||||
|
||||
provides = sorted(js_source.provides)
|
||||
requires = sorted(js_source.requires)
|
||||
module = 'true' if js_source.is_goog_module else 'false'
|
||||
|
||||
return 'goog.addDependency(\'%s\', %s, %s, %s);\n' % (
|
||||
path, provides, requires, module)
|
||||
|
||||
|
||||
def _GetOptionsParser():
|
||||
"""Get the options parser."""
|
||||
|
||||
parser = optparse.OptionParser(__doc__)
|
||||
|
||||
parser.add_option('--output_file',
|
||||
dest='output_file',
|
||||
action='store',
|
||||
help=('If specified, write output to this path instead of '
|
||||
'writing to standard output.'))
|
||||
parser.add_option('--root',
|
||||
dest='roots',
|
||||
default=[],
|
||||
action='append',
|
||||
help='A root directory to scan for JS source files. '
|
||||
'Paths of JS files in generated deps file will be '
|
||||
'relative to this path. This flag may be specified '
|
||||
'multiple times.')
|
||||
parser.add_option('--root_with_prefix',
|
||||
dest='roots_with_prefix',
|
||||
default=[],
|
||||
action='append',
|
||||
help='A root directory to scan for JS source files, plus '
|
||||
'a prefix (if either contains a space, surround with '
|
||||
'quotes). Paths in generated deps file will be relative '
|
||||
'to the root, but preceded by the prefix. This flag '
|
||||
'may be specified multiple times.')
|
||||
parser.add_option('--path_with_depspath',
|
||||
dest='paths_with_depspath',
|
||||
default=[],
|
||||
action='append',
|
||||
help='A path to a source file and an alternate path to '
|
||||
'the file in the generated deps file (if either contains '
|
||||
'a space, surround with whitespace). This flag may be '
|
||||
'specified multiple times.')
|
||||
return parser
|
||||
|
||||
|
||||
def _NormalizePathSeparators(path):
|
||||
"""Replaces OS-specific path separators with POSIX-style slashes.
|
||||
|
||||
Args:
|
||||
path: str, A file path.
|
||||
|
||||
Returns:
|
||||
str, The path with any OS-specific path separators (such as backslash on
|
||||
Windows) replaced with URL-compatible forward slashes. A no-op on systems
|
||||
that use POSIX paths.
|
||||
"""
|
||||
return path.replace(os.sep, posixpath.sep)
|
||||
|
||||
|
||||
def _GetRelativePathToSourceDict(root, prefix=''):
|
||||
"""Scans a top root directory for .js sources.
|
||||
|
||||
Args:
|
||||
root: str, Root directory.
|
||||
prefix: str, Prefix for returned paths.
|
||||
|
||||
Returns:
|
||||
dict, A map of relative paths (with prefix, if given), to source.Source
|
||||
objects.
|
||||
"""
|
||||
# Remember and restore the cwd when we're done. We work from the root so
|
||||
# that paths are relative from the root.
|
||||
start_wd = os.getcwd()
|
||||
os.chdir(root)
|
||||
|
||||
path_to_source = {}
|
||||
for path in treescan.ScanTreeForJsFiles('.'):
|
||||
prefixed_path = _NormalizePathSeparators(os.path.join(prefix, path))
|
||||
path_to_source[prefixed_path] = source.Source(source.GetFileContents(path))
|
||||
|
||||
os.chdir(start_wd)
|
||||
|
||||
return path_to_source
|
||||
|
||||
|
||||
def _GetPair(s):
|
||||
"""Return a string as a shell-parsed tuple. Two values expected."""
|
||||
try:
|
||||
# shlex uses '\' as an escape character, so they must be escaped.
|
||||
s = s.replace('\\', '\\\\')
|
||||
first, second = shlex.split(s)
|
||||
return (first, second)
|
||||
except:
|
||||
raise Exception('Unable to parse input line as a pair: %s' % s)
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI frontend to MakeDepsFile."""
|
||||
logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
|
||||
level=logging.INFO)
|
||||
options, args = _GetOptionsParser().parse_args()
|
||||
|
||||
path_to_source = {}
|
||||
|
||||
# Roots without prefixes
|
||||
for root in options.roots:
|
||||
path_to_source.update(_GetRelativePathToSourceDict(root))
|
||||
|
||||
# Roots with prefixes
|
||||
for root_and_prefix in options.roots_with_prefix:
|
||||
root, prefix = _GetPair(root_and_prefix)
|
||||
path_to_source.update(_GetRelativePathToSourceDict(root, prefix=prefix))
|
||||
|
||||
# Source paths
|
||||
for path in args:
|
||||
path_to_source[path] = source.Source(source.GetFileContents(path))
|
||||
|
||||
# Source paths with alternate deps paths
|
||||
for path_with_depspath in options.paths_with_depspath:
|
||||
srcpath, depspath = _GetPair(path_with_depspath)
|
||||
path_to_source[depspath] = source.Source(source.GetFileContents(srcpath))
|
||||
|
||||
# Make our output pipe.
|
||||
if options.output_file:
|
||||
out = open(options.output_file, 'w')
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
out.write('// This file was autogenerated by %s.\n' % sys.argv[0])
|
||||
out.write('// Please do not edit.\n')
|
||||
|
||||
out.write(MakeDepsFile(path_to_source))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,135 @@
|
|||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Utility to use the Closure Compiler CLI from Python."""
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
# Pulls just the major and minor version numbers from the first line of
|
||||
# 'java -version'. Versions are in the format of [0-9]+\.[0-9]+\..* See:
|
||||
# http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
|
||||
_VERSION_REGEX = re.compile(r'"([0-9]+)\.([0-9]+)')
|
||||
|
||||
|
||||
class JsCompilerError(Exception):
|
||||
"""Raised if there's an error in calling the compiler."""
|
||||
pass
|
||||
|
||||
|
||||
def _GetJavaVersionString():
|
||||
"""Get the version string from the Java VM."""
|
||||
return subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def _ParseJavaVersion(version_string):
|
||||
"""Returns a 2-tuple for the current version of Java installed.
|
||||
|
||||
Args:
|
||||
version_string: String of the Java version (e.g. '1.7.2-ea').
|
||||
|
||||
Returns:
|
||||
The major and minor versions, as a 2-tuple (e.g. (1, 7)).
|
||||
"""
|
||||
match = _VERSION_REGEX.search(version_string)
|
||||
if match:
|
||||
version = tuple(int(x, 10) for x in match.groups())
|
||||
assert len(version) == 2
|
||||
return version
|
||||
|
||||
|
||||
def _JavaSupports32BitMode():
|
||||
"""Determines whether the JVM supports 32-bit mode on the platform."""
|
||||
# Suppresses process output to stderr and stdout from showing up in the
|
||||
# console as we're only trying to determine 32-bit JVM support.
|
||||
supported = False
|
||||
try:
|
||||
devnull = open(os.devnull, 'wb')
|
||||
return subprocess.call(
|
||||
['java', '-d32', '-version'], stdout=devnull, stderr=devnull) == 0
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
devnull.close()
|
||||
return supported
|
||||
|
||||
|
||||
def _GetJsCompilerArgs(compiler_jar_path, java_version, source_paths,
|
||||
jvm_flags, compiler_flags):
|
||||
"""Assembles arguments for call to JsCompiler."""
|
||||
|
||||
if java_version < (1, 7):
|
||||
raise JsCompilerError('Closure Compiler requires Java 1.7 or higher. '
|
||||
'Please visit http://www.java.com/getjava')
|
||||
|
||||
args = ['java']
|
||||
|
||||
# Add JVM flags we believe will produce the best performance. See
|
||||
# https://groups.google.com/forum/#!topic/closure-library-discuss/7w_O9-vzlj4
|
||||
|
||||
# Attempt 32-bit mode if available (Java 7 on Mac OS X does not support 32-bit
|
||||
# mode, for example).
|
||||
if _JavaSupports32BitMode():
|
||||
args += ['-d32']
|
||||
|
||||
# Prefer the "client" VM.
|
||||
args += ['-client']
|
||||
|
||||
# Add JVM flags, if any
|
||||
if jvm_flags:
|
||||
args += jvm_flags
|
||||
|
||||
# Add the application JAR.
|
||||
args += ['-jar', compiler_jar_path]
|
||||
|
||||
for path in source_paths:
|
||||
args += ['--js', path]
|
||||
|
||||
# Add compiler flags, if any.
|
||||
if compiler_flags:
|
||||
args += compiler_flags
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def Compile(compiler_jar_path, source_paths,
|
||||
jvm_flags=None,
|
||||
compiler_flags=None):
|
||||
"""Prepares command-line call to Closure Compiler.
|
||||
|
||||
Args:
|
||||
compiler_jar_path: Path to the Closure compiler .jar file.
|
||||
source_paths: Source paths to build, in order.
|
||||
jvm_flags: A list of additional flags to pass on to JVM.
|
||||
compiler_flags: A list of additional flags to pass on to Closure Compiler.
|
||||
|
||||
Returns:
|
||||
The compiled source, as a string, or None if compilation failed.
|
||||
"""
|
||||
|
||||
java_version = _ParseJavaVersion(_GetJavaVersionString())
|
||||
|
||||
args = _GetJsCompilerArgs(
|
||||
compiler_jar_path, java_version, source_paths, jvm_flags, compiler_flags)
|
||||
|
||||
logging.info('Compiling with the following command: %s', ' '.join(args))
|
||||
|
||||
try:
|
||||
return subprocess.check_output(args)
|
||||
except subprocess.CalledProcessError:
|
||||
raise JsCompilerError('JavaScript compilation failed.')
|
|
@ -0,0 +1,127 @@
|
|||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Scans a source JS file for its provided and required namespaces.
|
||||
|
||||
Simple class to scan a JavaScript file and express its dependencies.
|
||||
"""
|
||||
|
||||
__author__ = 'nnaze@google.com'
|
||||
|
||||
|
||||
import re
|
||||
|
||||
_BASE_REGEX_STRING = r'^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
|
||||
_MODULE_REGEX = re.compile(_BASE_REGEX_STRING % 'module')
|
||||
_PROVIDE_REGEX = re.compile(_BASE_REGEX_STRING % 'provide')
|
||||
|
||||
_REQUIRE_REGEX_STRING = (r'^\s*(?:(?:var|let|const)\s+[a-zA-Z_$][a-zA-Z0-9$_]*'
|
||||
r'\s*=\s*)?goog\.require\(\s*[\'"](.+)[\'"]\s*\)')
|
||||
_REQUIRES_REGEX = re.compile(_REQUIRE_REGEX_STRING)
|
||||
|
||||
|
||||
class Source(object):
|
||||
"""Scans a JavaScript source for its provided and required namespaces."""
|
||||
|
||||
# Matches a "/* ... */" comment.
|
||||
# Note: We can't definitively distinguish a "/*" in a string literal without a
|
||||
# state machine tokenizer. We'll assume that a line starting with whitespace
|
||||
# and "/*" is a comment.
|
||||
_COMMENT_REGEX = re.compile(
|
||||
r"""
|
||||
^\s* # Start of a new line and whitespace
|
||||
/\* # Opening "/*"
|
||||
.*? # Non greedy match of any characters (including newlines)
|
||||
\*/ # Closing "*/""",
|
||||
re.MULTILINE | re.DOTALL | re.VERBOSE)
|
||||
|
||||
def __init__(self, source):
|
||||
"""Initialize a source.
|
||||
|
||||
Args:
|
||||
source: str, The JavaScript source.
|
||||
"""
|
||||
|
||||
self.provides = set()
|
||||
self.requires = set()
|
||||
self.is_goog_module = False
|
||||
|
||||
self._source = source
|
||||
self._ScanSource()
|
||||
|
||||
def GetSource(self):
|
||||
"""Get the source as a string."""
|
||||
return self._source
|
||||
|
||||
@classmethod
|
||||
def _StripComments(cls, source):
|
||||
return cls._COMMENT_REGEX.sub('', source)
|
||||
|
||||
@classmethod
|
||||
def _HasProvideGoogFlag(cls, source):
|
||||
"""Determines whether the @provideGoog flag is in a comment."""
|
||||
for comment_content in cls._COMMENT_REGEX.findall(source):
|
||||
if '@provideGoog' in comment_content:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _ScanSource(self):
|
||||
"""Fill in provides and requires by scanning the source."""
|
||||
|
||||
stripped_source = self._StripComments(self.GetSource())
|
||||
|
||||
source_lines = stripped_source.splitlines()
|
||||
for line in source_lines:
|
||||
match = _PROVIDE_REGEX.match(line)
|
||||
if match:
|
||||
self.provides.add(match.group(1))
|
||||
match = _MODULE_REGEX.match(line)
|
||||
if match:
|
||||
self.provides.add(match.group(1))
|
||||
self.is_goog_module = True
|
||||
match = _REQUIRES_REGEX.match(line)
|
||||
if match:
|
||||
self.requires.add(match.group(1))
|
||||
|
||||
# Closure's base file implicitly provides 'goog'.
|
||||
# This is indicated with the @provideGoog flag.
|
||||
if self._HasProvideGoogFlag(self.GetSource()):
|
||||
|
||||
if len(self.provides) or len(self.requires):
|
||||
raise Exception(
|
||||
'Base file should not provide or require namespaces.')
|
||||
|
||||
self.provides.add('goog')
|
||||
|
||||
|
||||
def GetFileContents(path):
|
||||
"""Get a file's contents as a string.
|
||||
|
||||
Args:
|
||||
path: str, Path to file.
|
||||
|
||||
Returns:
|
||||
str, Contents of file.
|
||||
|
||||
Raises:
|
||||
IOError: An error occurred opening or reading the file.
|
||||
|
||||
"""
|
||||
fileobj = open(path)
|
||||
try:
|
||||
return fileobj.read()
|
||||
finally:
|
||||
fileobj.close()
|
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Shared utility functions for scanning directory trees."""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
# Matches a .js file path.
|
||||
_JS_FILE_REGEX = re.compile(r'^.+\.js$')
|
||||
|
||||
|
||||
def ScanTreeForJsFiles(root):
|
||||
"""Scans a directory tree for JavaScript files.
|
||||
|
||||
Args:
|
||||
root: str, Path to a root directory.
|
||||
|
||||
Returns:
|
||||
An iterable of paths to JS files, relative to cwd.
|
||||
"""
|
||||
return ScanTree(root, path_filter=_JS_FILE_REGEX)
|
||||
|
||||
|
||||
def ScanTree(root, path_filter=None, ignore_hidden=True):
|
||||
"""Scans a directory tree for files.
|
||||
|
||||
Args:
|
||||
root: str, Path to a root directory.
|
||||
path_filter: A regular expression filter. If set, only paths matching
|
||||
the path_filter are returned.
|
||||
ignore_hidden: If True, do not follow or return hidden directories or files
|
||||
(those starting with a '.' character).
|
||||
|
||||
Yields:
|
||||
A string path to files, relative to cwd.
|
||||
"""
|
||||
|
||||
def OnError(os_error):
|
||||
raise os_error
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(root, onerror=OnError):
|
||||
# os.walk allows us to modify dirnames to prevent decent into particular
|
||||
# directories. Avoid hidden directories.
|
||||
for dirname in dirnames:
|
||||
if ignore_hidden and dirname.startswith('.'):
|
||||
dirnames.remove(dirname)
|
||||
|
||||
for filename in filenames:
|
||||
|
||||
# nothing that starts with '.'
|
||||
if ignore_hidden and filename.startswith('.'):
|
||||
continue
|
||||
|
||||
fullpath = os.path.join(dirpath, filename)
|
||||
|
||||
if path_filter and not path_filter.match(fullpath):
|
||||
continue
|
||||
|
||||
yield os.path.normpath(fullpath)
|
|
@ -0,0 +1,590 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Calculates JavaScript dependencies without requiring Google's build system.
|
||||
|
||||
This tool is deprecated and is provided for legacy users.
|
||||
See build/closurebuilder.py and build/depswriter.py for the current tools.
|
||||
|
||||
It iterates over a number of search paths and builds a dependency tree. With
|
||||
the inputs provided, it walks the dependency tree and outputs all the files
|
||||
required for compilation.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
import distutils.version
|
||||
except ImportError:
|
||||
# distutils is not available in all environments
|
||||
distutils = None
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
_BASE_REGEX_STRING = '^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
|
||||
req_regex = re.compile(_BASE_REGEX_STRING % 'require')
|
||||
prov_regex = re.compile(_BASE_REGEX_STRING % 'provide')
|
||||
ns_regex = re.compile('^ns:((\w+\.)*(\w+))$')
|
||||
version_regex = re.compile('[\.0-9]+')
|
||||
|
||||
|
||||
def IsValidFile(ref):
|
||||
"""Returns true if the provided reference is a file and exists."""
|
||||
return os.path.isfile(ref)
|
||||
|
||||
|
||||
def IsJsFile(ref):
|
||||
"""Returns true if the provided reference is a Javascript file."""
|
||||
return ref.endswith('.js')
|
||||
|
||||
|
||||
def IsNamespace(ref):
|
||||
"""Returns true if the provided reference is a namespace."""
|
||||
return re.match(ns_regex, ref) is not None
|
||||
|
||||
|
||||
def IsDirectory(ref):
|
||||
"""Returns true if the provided reference is a directory."""
|
||||
return os.path.isdir(ref)
|
||||
|
||||
|
||||
def ExpandDirectories(refs):
|
||||
"""Expands any directory references into inputs.
|
||||
|
||||
Description:
|
||||
Looks for any directories in the provided references. Found directories
|
||||
are recursively searched for .js files, which are then added to the result
|
||||
list.
|
||||
|
||||
Args:
|
||||
refs: a list of references such as files, directories, and namespaces
|
||||
|
||||
Returns:
|
||||
A list of references with directories removed and replaced by any
|
||||
.js files that are found in them. Also, the paths will be normalized.
|
||||
"""
|
||||
result = []
|
||||
for ref in refs:
|
||||
if IsDirectory(ref):
|
||||
# Disable 'Unused variable' for subdirs
|
||||
# pylint: disable=unused-variable
|
||||
for (directory, subdirs, filenames) in os.walk(ref):
|
||||
for filename in filenames:
|
||||
if IsJsFile(filename):
|
||||
result.append(os.path.join(directory, filename))
|
||||
else:
|
||||
result.append(ref)
|
||||
return map(os.path.normpath, result)
|
||||
|
||||
|
||||
class DependencyInfo(object):
|
||||
"""Represents a dependency that is used to build and walk a tree."""
|
||||
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.provides = []
|
||||
self.requires = []
|
||||
|
||||
def __str__(self):
|
||||
return '%s Provides: %s Requires: %s' % (self.filename,
|
||||
repr(self.provides),
|
||||
repr(self.requires))
|
||||
|
||||
|
||||
def BuildDependenciesFromFiles(files):
|
||||
"""Build a list of dependencies from a list of files.
|
||||
|
||||
Description:
|
||||
Takes a list of files, extracts their provides and requires, and builds
|
||||
out a list of dependency objects.
|
||||
|
||||
Args:
|
||||
files: a list of files to be parsed for goog.provides and goog.requires.
|
||||
|
||||
Returns:
|
||||
A list of dependency objects, one for each file in the files argument.
|
||||
"""
|
||||
result = []
|
||||
filenames = set()
|
||||
for filename in files:
|
||||
if filename in filenames:
|
||||
continue
|
||||
|
||||
# Python 3 requires the file encoding to be specified
|
||||
if (sys.version_info[0] < 3):
|
||||
file_handle = open(filename, 'r')
|
||||
else:
|
||||
file_handle = open(filename, 'r', encoding='utf8')
|
||||
|
||||
try:
|
||||
dep = CreateDependencyInfo(filename, file_handle)
|
||||
result.append(dep)
|
||||
finally:
|
||||
file_handle.close()
|
||||
|
||||
filenames.add(filename)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def CreateDependencyInfo(filename, source):
|
||||
"""Create dependency info.
|
||||
|
||||
Args:
|
||||
filename: Filename for source.
|
||||
source: File-like object containing source.
|
||||
|
||||
Returns:
|
||||
A DependencyInfo object with provides and requires filled.
|
||||
"""
|
||||
dep = DependencyInfo(filename)
|
||||
for line in source:
|
||||
if re.match(req_regex, line):
|
||||
dep.requires.append(re.search(req_regex, line).group(1))
|
||||
if re.match(prov_regex, line):
|
||||
dep.provides.append(re.search(prov_regex, line).group(1))
|
||||
return dep
|
||||
|
||||
|
||||
def BuildDependencyHashFromDependencies(deps):
|
||||
"""Builds a hash for searching dependencies by the namespaces they provide.
|
||||
|
||||
Description:
|
||||
Dependency objects can provide multiple namespaces. This method enumerates
|
||||
the provides of each dependency and adds them to a hash that can be used
|
||||
to easily resolve a given dependency by a namespace it provides.
|
||||
|
||||
Args:
|
||||
deps: a list of dependency objects used to build the hash.
|
||||
|
||||
Raises:
|
||||
Exception: If a multiple files try to provide the same namepace.
|
||||
|
||||
Returns:
|
||||
A hash table { namespace: dependency } that can be used to resolve a
|
||||
dependency by a namespace it provides.
|
||||
"""
|
||||
dep_hash = {}
|
||||
for dep in deps:
|
||||
for provide in dep.provides:
|
||||
if provide in dep_hash:
|
||||
raise Exception('Duplicate provide (%s) in (%s, %s)' % (
|
||||
provide,
|
||||
dep_hash[provide].filename,
|
||||
dep.filename))
|
||||
dep_hash[provide] = dep
|
||||
return dep_hash
|
||||
|
||||
|
||||
def CalculateDependencies(paths, inputs):
|
||||
"""Calculates the dependencies for given inputs.
|
||||
|
||||
Description:
|
||||
This method takes a list of paths (files, directories) and builds a
|
||||
searchable data structure based on the namespaces that each .js file
|
||||
provides. It then parses through each input, resolving dependencies
|
||||
against this data structure. The final output is a list of files,
|
||||
including the inputs, that represent all of the code that is needed to
|
||||
compile the given inputs.
|
||||
|
||||
Args:
|
||||
paths: the references (files, directories) that are used to build the
|
||||
dependency hash.
|
||||
inputs: the inputs (files, directories, namespaces) that have dependencies
|
||||
that need to be calculated.
|
||||
|
||||
Raises:
|
||||
Exception: if a provided input is invalid.
|
||||
|
||||
Returns:
|
||||
A list of all files, including inputs, that are needed to compile the given
|
||||
inputs.
|
||||
"""
|
||||
deps = BuildDependenciesFromFiles(paths + inputs)
|
||||
search_hash = BuildDependencyHashFromDependencies(deps)
|
||||
result_list = []
|
||||
seen_list = []
|
||||
for input_file in inputs:
|
||||
if IsNamespace(input_file):
|
||||
namespace = re.search(ns_regex, input_file).group(1)
|
||||
if namespace not in search_hash:
|
||||
raise Exception('Invalid namespace (%s)' % namespace)
|
||||
input_file = search_hash[namespace].filename
|
||||
if not IsValidFile(input_file) or not IsJsFile(input_file):
|
||||
raise Exception('Invalid file (%s)' % input_file)
|
||||
seen_list.append(input_file)
|
||||
file_handle = open(input_file, 'r')
|
||||
try:
|
||||
for line in file_handle:
|
||||
if re.match(req_regex, line):
|
||||
require = re.search(req_regex, line).group(1)
|
||||
ResolveDependencies(require, search_hash, result_list, seen_list)
|
||||
finally:
|
||||
file_handle.close()
|
||||
result_list.append(input_file)
|
||||
|
||||
# All files depend on base.js, so put it first.
|
||||
base_js_path = FindClosureBasePath(paths)
|
||||
if base_js_path:
|
||||
result_list.insert(0, base_js_path)
|
||||
else:
|
||||
logging.warning('Closure Library base.js not found.')
|
||||
|
||||
return result_list
|
||||
|
||||
|
||||
def FindClosureBasePath(paths):
|
||||
"""Given a list of file paths, return Closure base.js path, if any.
|
||||
|
||||
Args:
|
||||
paths: A list of paths.
|
||||
|
||||
Returns:
|
||||
The path to Closure's base.js file including filename, if found.
|
||||
"""
|
||||
|
||||
for path in paths:
|
||||
pathname, filename = os.path.split(path)
|
||||
|
||||
if filename == 'base.js':
|
||||
f = open(path)
|
||||
|
||||
is_base = False
|
||||
|
||||
# Sanity check that this is the Closure base file. Check that this
|
||||
# is where goog is defined. This is determined by the @provideGoog
|
||||
# flag.
|
||||
for line in f:
|
||||
if '@provideGoog' in line:
|
||||
is_base = True
|
||||
break
|
||||
|
||||
f.close()
|
||||
|
||||
if is_base:
|
||||
return path
|
||||
|
||||
def ResolveDependencies(require, search_hash, result_list, seen_list):
|
||||
"""Takes a given requirement and resolves all of the dependencies for it.
|
||||
|
||||
Description:
|
||||
A given requirement may require other dependencies. This method
|
||||
recursively resolves all dependencies for the given requirement.
|
||||
|
||||
Raises:
|
||||
Exception: when require does not exist in the search_hash.
|
||||
|
||||
Args:
|
||||
require: the namespace to resolve dependencies for.
|
||||
search_hash: the data structure used for resolving dependencies.
|
||||
result_list: a list of filenames that have been calculated as dependencies.
|
||||
This variable is the output for this function.
|
||||
seen_list: a list of filenames that have been 'seen'. This is required
|
||||
for the dependency->dependant ordering.
|
||||
"""
|
||||
if require not in search_hash:
|
||||
raise Exception('Missing provider for (%s)' % require)
|
||||
|
||||
dep = search_hash[require]
|
||||
if not dep.filename in seen_list:
|
||||
seen_list.append(dep.filename)
|
||||
for sub_require in dep.requires:
|
||||
ResolveDependencies(sub_require, search_hash, result_list, seen_list)
|
||||
result_list.append(dep.filename)
|
||||
|
||||
|
||||
def GetDepsLine(dep, base_path):
|
||||
"""Returns a JS string for a dependency statement in the deps.js file.
|
||||
|
||||
Args:
|
||||
dep: The dependency that we're printing.
|
||||
base_path: The path to Closure's base.js including filename.
|
||||
"""
|
||||
return 'goog.addDependency("%s", %s, %s);' % (
|
||||
GetRelpath(dep.filename, base_path), dep.provides, dep.requires)
|
||||
|
||||
|
||||
def GetRelpath(path, start):
|
||||
"""Return a relative path to |path| from |start|."""
|
||||
# NOTE: Python 2.6 provides os.path.relpath, which has almost the same
|
||||
# functionality as this function. Since we want to support 2.4, we have
|
||||
# to implement it manually. :(
|
||||
path_list = os.path.abspath(os.path.normpath(path)).split(os.sep)
|
||||
start_list = os.path.abspath(
|
||||
os.path.normpath(os.path.dirname(start))).split(os.sep)
|
||||
|
||||
common_prefix_count = 0
|
||||
for i in range(0, min(len(path_list), len(start_list))):
|
||||
if path_list[i] != start_list[i]:
|
||||
break
|
||||
common_prefix_count += 1
|
||||
|
||||
# Always use forward slashes, because this will get expanded to a url,
|
||||
# not a file path.
|
||||
return '/'.join(['..'] * (len(start_list) - common_prefix_count) +
|
||||
path_list[common_prefix_count:])
|
||||
|
||||
|
||||
def PrintLine(msg, out):
|
||||
out.write(msg)
|
||||
out.write('\n')
|
||||
|
||||
|
||||
def PrintDeps(source_paths, deps, out):
|
||||
"""Print out a deps.js file from a list of source paths.
|
||||
|
||||
Args:
|
||||
source_paths: Paths that we should generate dependency info for.
|
||||
deps: Paths that provide dependency info. Their dependency info should
|
||||
not appear in the deps file.
|
||||
out: The output file.
|
||||
|
||||
Returns:
|
||||
True on success, false if it was unable to find the base path
|
||||
to generate deps relative to.
|
||||
"""
|
||||
base_path = FindClosureBasePath(source_paths + deps)
|
||||
if not base_path:
|
||||
return False
|
||||
|
||||
PrintLine('// This file was autogenerated by calcdeps.py', out)
|
||||
excludesSet = set(deps)
|
||||
|
||||
for dep in BuildDependenciesFromFiles(source_paths + deps):
|
||||
if not dep.filename in excludesSet:
|
||||
PrintLine(GetDepsLine(dep, base_path), out)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def PrintScript(source_paths, out):
|
||||
for index, dep in enumerate(source_paths):
|
||||
PrintLine('// Input %d' % index, out)
|
||||
f = open(dep, 'r')
|
||||
PrintLine(f.read(), out)
|
||||
f.close()
|
||||
|
||||
|
||||
def GetJavaVersion():
|
||||
"""Returns the string for the current version of Java installed."""
|
||||
proc = subprocess.Popen(['java', '-version'], stderr=subprocess.PIPE)
|
||||
proc.wait()
|
||||
version_line = proc.stderr.read().splitlines()[0]
|
||||
return version_regex.search(version_line).group()
|
||||
|
||||
|
||||
def FilterByExcludes(options, files):
|
||||
"""Filters the given files by the exlusions specified at the command line.
|
||||
|
||||
Args:
|
||||
options: The flags to calcdeps.
|
||||
files: The files to filter.
|
||||
Returns:
|
||||
A list of files.
|
||||
"""
|
||||
excludes = []
|
||||
if options.excludes:
|
||||
excludes = ExpandDirectories(options.excludes)
|
||||
|
||||
excludesSet = set(excludes)
|
||||
return [i for i in files if not i in excludesSet]
|
||||
|
||||
|
||||
def GetPathsFromOptions(options):
|
||||
"""Generates the path files from flag options.
|
||||
|
||||
Args:
|
||||
options: The flags to calcdeps.
|
||||
Returns:
|
||||
A list of files in the specified paths. (strings).
|
||||
"""
|
||||
|
||||
search_paths = options.paths
|
||||
if not search_paths:
|
||||
search_paths = ['.'] # Add default folder if no path is specified.
|
||||
|
||||
search_paths = ExpandDirectories(search_paths)
|
||||
return FilterByExcludes(options, search_paths)
|
||||
|
||||
|
||||
def GetInputsFromOptions(options):
|
||||
"""Generates the inputs from flag options.
|
||||
|
||||
Args:
|
||||
options: The flags to calcdeps.
|
||||
Returns:
|
||||
A list of inputs (strings).
|
||||
"""
|
||||
inputs = options.inputs
|
||||
if not inputs: # Parse stdin
|
||||
logging.info('No inputs specified. Reading from stdin...')
|
||||
inputs = filter(None, [line.strip('\n') for line in sys.stdin.readlines()])
|
||||
|
||||
logging.info('Scanning files...')
|
||||
inputs = ExpandDirectories(inputs)
|
||||
|
||||
return FilterByExcludes(options, inputs)
|
||||
|
||||
|
||||
def Compile(compiler_jar_path, source_paths, out, flags=None):
|
||||
"""Prepares command-line call to Closure compiler.
|
||||
|
||||
Args:
|
||||
compiler_jar_path: Path to the Closure compiler .jar file.
|
||||
source_paths: Source paths to build, in order.
|
||||
flags: A list of additional flags to pass on to Closure compiler.
|
||||
"""
|
||||
args = ['java', '-jar', compiler_jar_path]
|
||||
for path in source_paths:
|
||||
args += ['--js', path]
|
||||
|
||||
if flags:
|
||||
args += flags
|
||||
|
||||
logging.info('Compiling with the following command: %s', ' '.join(args))
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
(stdoutdata, stderrdata) = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
logging.error('JavaScript compilation failed.')
|
||||
sys.exit(1)
|
||||
else:
|
||||
out.write(stdoutdata)
|
||||
|
||||
|
||||
def main():
|
||||
"""The entrypoint for this script."""
|
||||
|
||||
logging.basicConfig(format='calcdeps.py: %(message)s', level=logging.INFO)
|
||||
|
||||
usage = 'usage: %prog [options] arg'
|
||||
parser = optparse.OptionParser(usage)
|
||||
parser.add_option('-i',
|
||||
'--input',
|
||||
dest='inputs',
|
||||
action='append',
|
||||
help='The inputs to calculate dependencies for. Valid '
|
||||
'values can be files, directories, or namespaces '
|
||||
'(ns:goog.net.XhrIo). Only relevant to "list" and '
|
||||
'"script" output.')
|
||||
parser.add_option('-p',
|
||||
'--path',
|
||||
dest='paths',
|
||||
action='append',
|
||||
help='The paths that should be traversed to build the '
|
||||
'dependencies.')
|
||||
parser.add_option('-d',
|
||||
'--dep',
|
||||
dest='deps',
|
||||
action='append',
|
||||
help='Directories or files that should be traversed to '
|
||||
'find required dependencies for the deps file. '
|
||||
'Does not generate dependency information for names '
|
||||
'provided by these files. Only useful in "deps" mode.')
|
||||
parser.add_option('-e',
|
||||
'--exclude',
|
||||
dest='excludes',
|
||||
action='append',
|
||||
help='Files or directories to exclude from the --path '
|
||||
'and --input flags')
|
||||
parser.add_option('-o',
|
||||
'--output_mode',
|
||||
dest='output_mode',
|
||||
action='store',
|
||||
default='list',
|
||||
help='The type of output to generate from this script. '
|
||||
'Options are "list" for a list of filenames, "script" '
|
||||
'for a single script containing the contents of all the '
|
||||
'file, "deps" to generate a deps.js file for all '
|
||||
'paths, or "compiled" to produce compiled output with '
|
||||
'the Closure compiler.')
|
||||
parser.add_option('-c',
|
||||
'--compiler_jar',
|
||||
dest='compiler_jar',
|
||||
action='store',
|
||||
help='The location of the Closure compiler .jar file.')
|
||||
parser.add_option('-f',
|
||||
'--compiler_flag',
|
||||
'--compiler_flags', # for backwards compatability
|
||||
dest='compiler_flags',
|
||||
action='append',
|
||||
help='Additional flag to pass to the Closure compiler. '
|
||||
'May be specified multiple times to pass multiple flags.')
|
||||
parser.add_option('--output_file',
|
||||
dest='output_file',
|
||||
action='store',
|
||||
help=('If specified, write output to this path instead of '
|
||||
'writing to standard output.'))
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
search_paths = GetPathsFromOptions(options)
|
||||
|
||||
if options.output_file:
|
||||
out = open(options.output_file, 'w')
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
if options.output_mode == 'deps':
|
||||
result = PrintDeps(search_paths, ExpandDirectories(options.deps or []), out)
|
||||
if not result:
|
||||
logging.error('Could not find Closure Library in the specified paths')
|
||||
sys.exit(1)
|
||||
|
||||
return
|
||||
|
||||
inputs = GetInputsFromOptions(options)
|
||||
|
||||
logging.info('Finding Closure dependencies...')
|
||||
deps = CalculateDependencies(search_paths, inputs)
|
||||
output_mode = options.output_mode
|
||||
|
||||
if output_mode == 'script':
|
||||
PrintScript(deps, out)
|
||||
elif output_mode == 'list':
|
||||
# Just print out a dep per line
|
||||
for dep in deps:
|
||||
PrintLine(dep, out)
|
||||
elif output_mode == 'compiled':
|
||||
# Make sure a .jar is specified.
|
||||
if not options.compiler_jar:
|
||||
logging.error('--compiler_jar flag must be specified if --output is '
|
||||
'"compiled"')
|
||||
sys.exit(1)
|
||||
|
||||
# User friendly version check.
|
||||
if distutils and not (distutils.version.LooseVersion(GetJavaVersion()) >
|
||||
distutils.version.LooseVersion('1.6')):
|
||||
logging.error('Closure Compiler requires Java 1.6 or higher.')
|
||||
logging.error('Please visit http://www.java.com/getjava')
|
||||
sys.exit(1)
|
||||
|
||||
Compile(options.compiler_jar, deps, out, options.compiler_flags)
|
||||
|
||||
else:
|
||||
logging.error('Invalid value for --output flag.')
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,221 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Automatically converts codebases over to goog.scope.
|
||||
|
||||
Usage:
|
||||
cd path/to/my/dir;
|
||||
../../../../javascript/closure/bin/scopify.py
|
||||
|
||||
Scans every file in this directory, recursively. Looks for existing
|
||||
goog.scope calls, and goog.require'd symbols. If it makes sense to
|
||||
generate a goog.scope call for the file, then we will do so, and
|
||||
try to auto-generate some aliases based on the goog.require'd symbols.
|
||||
|
||||
Known Issues:
|
||||
|
||||
When a file is goog.scope'd, the file contents will be indented +2.
|
||||
This may put some lines over 80 chars. These will need to be fixed manually.
|
||||
|
||||
We will only try to create aliases for capitalized names. We do not check
|
||||
to see if those names will conflict with any existing locals.
|
||||
|
||||
This creates merge conflicts for every line of every outstanding change.
|
||||
If you intend to run this on your codebase, make sure your team members
|
||||
know. Better yet, send them this script so that they can scopify their
|
||||
outstanding changes and "accept theirs".
|
||||
|
||||
When an alias is "captured", it can no longer be stubbed out for testing.
|
||||
Run your tests.
|
||||
|
||||
"""
|
||||
|
||||
__author__ = 'nicksantos@google.com (Nick Santos)'
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
REQUIRES_RE = re.compile(r"goog.require\('([^']*)'\)")
|
||||
|
||||
# Edit this manually if you want something to "always" be aliased.
|
||||
# TODO(nicksantos): Add a flag for this.
|
||||
DEFAULT_ALIASES = {}
|
||||
|
||||
def Transform(lines):
|
||||
"""Converts the contents of a file into javascript that uses goog.scope.
|
||||
|
||||
Arguments:
|
||||
lines: A list of strings, corresponding to each line of the file.
|
||||
Returns:
|
||||
A new list of strings, or None if the file was not modified.
|
||||
"""
|
||||
requires = []
|
||||
|
||||
# Do an initial scan to be sure that this file can be processed.
|
||||
for line in lines:
|
||||
# Skip this file if it has already been scopified.
|
||||
if line.find('goog.scope') != -1:
|
||||
return None
|
||||
|
||||
# If there are any global vars or functions, then we also have
|
||||
# to skip the whole file. We might be able to deal with this
|
||||
# more elegantly.
|
||||
if line.find('var ') == 0 or line.find('function ') == 0:
|
||||
return None
|
||||
|
||||
for match in REQUIRES_RE.finditer(line):
|
||||
requires.append(match.group(1))
|
||||
|
||||
if len(requires) == 0:
|
||||
return None
|
||||
|
||||
# Backwards-sort the requires, so that when one is a substring of another,
|
||||
# we match the longer one first.
|
||||
for val in DEFAULT_ALIASES.values():
|
||||
if requires.count(val) == 0:
|
||||
requires.append(val)
|
||||
|
||||
requires.sort()
|
||||
requires.reverse()
|
||||
|
||||
# Generate a map of requires to their aliases
|
||||
aliases_to_globals = DEFAULT_ALIASES.copy()
|
||||
for req in requires:
|
||||
index = req.rfind('.')
|
||||
if index == -1:
|
||||
alias = req
|
||||
else:
|
||||
alias = req[(index + 1):]
|
||||
|
||||
# Don't scopify lowercase namespaces, because they may conflict with
|
||||
# local variables.
|
||||
if alias[0].isupper():
|
||||
aliases_to_globals[alias] = req
|
||||
|
||||
aliases_to_matchers = {}
|
||||
globals_to_aliases = {}
|
||||
for alias, symbol in aliases_to_globals.items():
|
||||
globals_to_aliases[symbol] = alias
|
||||
aliases_to_matchers[alias] = re.compile('\\b%s\\b' % symbol)
|
||||
|
||||
# Insert a goog.scope that aliases all required symbols.
|
||||
result = []
|
||||
|
||||
START = 0
|
||||
SEEN_REQUIRES = 1
|
||||
IN_SCOPE = 2
|
||||
|
||||
mode = START
|
||||
aliases_used = set()
|
||||
insertion_index = None
|
||||
num_blank_lines = 0
|
||||
for line in lines:
|
||||
if mode == START:
|
||||
result.append(line)
|
||||
|
||||
if re.search(REQUIRES_RE, line):
|
||||
mode = SEEN_REQUIRES
|
||||
|
||||
elif mode == SEEN_REQUIRES:
|
||||
if (line and
|
||||
not re.search(REQUIRES_RE, line) and
|
||||
not line.isspace()):
|
||||
# There should be two blank lines before goog.scope
|
||||
result += ['\n'] * 2
|
||||
result.append('goog.scope(function() {\n')
|
||||
insertion_index = len(result)
|
||||
result += ['\n'] * num_blank_lines
|
||||
mode = IN_SCOPE
|
||||
elif line.isspace():
|
||||
# Keep track of the number of blank lines before each block of code so
|
||||
# that we can move them after the goog.scope line if necessary.
|
||||
num_blank_lines += 1
|
||||
else:
|
||||
# Print the blank lines we saw before this code block
|
||||
result += ['\n'] * num_blank_lines
|
||||
num_blank_lines = 0
|
||||
result.append(line)
|
||||
|
||||
if mode == IN_SCOPE:
|
||||
for symbol in requires:
|
||||
if not symbol in globals_to_aliases:
|
||||
continue
|
||||
|
||||
alias = globals_to_aliases[symbol]
|
||||
matcher = aliases_to_matchers[alias]
|
||||
for match in matcher.finditer(line):
|
||||
# Check to make sure we're not in a string.
|
||||
# We do this by being as conservative as possible:
|
||||
# if there are any quote or double quote characters
|
||||
# before the symbol on this line, then bail out.
|
||||
before_symbol = line[:match.start(0)]
|
||||
if before_symbol.count('"') > 0 or before_symbol.count("'") > 0:
|
||||
continue
|
||||
|
||||
line = line.replace(match.group(0), alias)
|
||||
aliases_used.add(alias)
|
||||
|
||||
if line.isspace():
|
||||
# Truncate all-whitespace lines
|
||||
result.append('\n')
|
||||
else:
|
||||
result.append(line)
|
||||
|
||||
if len(aliases_used):
|
||||
aliases_used = [alias for alias in aliases_used]
|
||||
aliases_used.sort()
|
||||
aliases_used.reverse()
|
||||
for alias in aliases_used:
|
||||
symbol = aliases_to_globals[alias]
|
||||
result.insert(insertion_index,
|
||||
'var %s = %s;\n' % (alias, symbol))
|
||||
result.append('}); // goog.scope\n')
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def TransformFileAt(path):
|
||||
"""Converts a file into javascript that uses goog.scope.
|
||||
|
||||
Arguments:
|
||||
path: A path to a file.
|
||||
"""
|
||||
f = open(path)
|
||||
lines = Transform(f.readlines())
|
||||
if lines:
|
||||
f = open(path, 'w')
|
||||
for l in lines:
|
||||
f.write(l)
|
||||
f.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
if not len(args):
|
||||
args = '.'
|
||||
|
||||
for file_name in args:
|
||||
if os.path.isdir(file_name):
|
||||
for root, dirs, files in os.walk(file_name):
|
||||
for name in files:
|
||||
if name.endswith('.js') and \
|
||||
not os.path.islink(os.path.join(root, name)):
|
||||
TransformFileAt(os.path.join(root, name))
|
||||
else:
|
||||
if file_name.endswith('.js') and \
|
||||
not os.path.islink(file_name):
|
||||
TransformFileAt(file_name)
|
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,13 @@
|
|||
This file "00_test_list.txt" lists which files the test harness should run.
|
||||
|
||||
If you add new tests you can update it with
|
||||
|
||||
on windows
|
||||
|
||||
dir /b *.html >00_test_list.txt
|
||||
|
||||
on OSX / Linux
|
||||
|
||||
ls -1 *.html >00_test_list.txt
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
attribs/00_test_list.txt
|
||||
buffers/00_test_list.txt
|
||||
canvas/00_test_list.txt
|
||||
context/00_test_list.txt
|
||||
extensions/00_test_list.txt
|
||||
glsl/00_test_list.txt
|
||||
limits/00_test_list.txt
|
||||
misc/00_test_list.txt
|
||||
--min-version 1.0.2 ogles/00_test_list.txt
|
||||
programs/00_test_list.txt
|
||||
reading/00_test_list.txt
|
||||
renderbuffers/00_test_list.txt
|
||||
rendering/00_test_list.txt
|
||||
state/00_test_list.txt
|
||||
textures/00_test_list.txt
|
||||
typedarrays/00_test_list.txt
|
||||
uniforms/00_test_list.txt
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
--min-version 1.0.3 gl-bindAttribLocation-aliasing.html
|
||||
--min-version 1.0.3 gl-bindAttribLocation-matrix.html
|
||||
--min-version 1.0.4 gl-bindAttribLocation-repeated.html
|
||||
--min-version 1.0.2 gl-disabled-vertex-attrib.html
|
||||
gl-enable-vertex-attrib.html
|
||||
--min-version 1.0.3 gl-matrix-attributes.html
|
||||
--max-version 1.9.9 gl-vertex-attrib.html
|
||||
gl-vertexattribpointer.html
|
||||
gl-vertexattribpointer-offsets.html
|
||||
--min-version 1.0.2 gl-vertex-attrib-render.html
|
||||
gl-vertex-attrib-zero-issues.html
|
|
@ -0,0 +1,92 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<title>bindAttribLocation with aliasing</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
|
||||
<script id="vertexShader" type="text/something-not-javascript">
|
||||
precision mediump float;
|
||||
attribute $(type_1) a_1;
|
||||
attribute $(type_2) a_2;
|
||||
void main() {
|
||||
gl_Position = $(gl_Position_1) + $(gl_Position_2);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies combinations of valid, active attribute types cannot be bound to the same location with bindAttribLocation.");
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
|
||||
var typeInfo = [
|
||||
{ type: 'float', asVec4: 'vec4(0.0, $(var), 0.0, 1.0)' },
|
||||
{ type: 'vec2', asVec4: 'vec4($(var), 0.0, 1.0)' },
|
||||
{ type: 'vec3', asVec4: 'vec4($(var), 1.0)' },
|
||||
{ type: 'vec4', asVec4: '$(var)' },
|
||||
];
|
||||
var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
// Test all type combinations of a_1 and a_2.
|
||||
typeInfo.forEach(function(typeInfo1) {
|
||||
typeInfo.forEach(function(typeInfo2) {
|
||||
debug('attribute_1: ' + typeInfo1.type + ' attribute_2: ' + typeInfo2.type);
|
||||
var replaceParams = {
|
||||
type_1: typeInfo1.type,
|
||||
type_2: typeInfo2.type,
|
||||
gl_Position_1: wtu.replaceParams(typeInfo1.asVec4, {var: 'a_1'}),
|
||||
gl_Position_2: wtu.replaceParams(typeInfo2.asVec4, {var: 'a_2'})
|
||||
};
|
||||
var strVertexShader = wtu.replaceParams(wtu.getScript('vertexShader'), replaceParams);
|
||||
var glVertexShader = wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
|
||||
assertMsg(glVertexShader != null, "Vertex shader compiled successfully.");
|
||||
// Bind both a_1 and a_2 to the same position and verify the link fails.
|
||||
// Do so for all valid positions available.
|
||||
for (var l = 0; l < maxAttributes; l++) {
|
||||
var glProgram = gl.createProgram();
|
||||
gl.bindAttribLocation(glProgram, l, 'a_1');
|
||||
gl.bindAttribLocation(glProgram, l, 'a_2');
|
||||
gl.attachShader(glProgram, glVertexShader);
|
||||
gl.attachShader(glProgram, glFragmentShader);
|
||||
gl.linkProgram(glProgram);
|
||||
assertMsg(!gl.getProgramParameter(glProgram, gl.LINK_STATUS), "Link should fail when both types are aliased to location " + l);
|
||||
}
|
||||
});
|
||||
});
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,121 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<title>WebGL bindAttribLocation with Matrix Attributes Conformance Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies that vectors placed via bindAttribLocation right after matricies will fail if there is insufficient room for the matrix.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
|
||||
// Make sure we have room for at least a mat4.
|
||||
var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
debug('MAX_VERTEX_ATTRIBUTES is ' + maxAttributes);
|
||||
shouldBeGreaterThanOrEqual('maxAttributes', '4');
|
||||
|
||||
var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
|
||||
|
||||
// Given a matrix dimension, load a vertex shader with a matrix of that dimension
|
||||
// and a vector. Ensure that both the vector and matrix are active attributes.
|
||||
// Return the compiled vertex shader.
|
||||
function loadVertexShader(numMatrixDimensions) {
|
||||
var strVertexShader =
|
||||
'attribute mat' + numMatrixDimensions + ' matrix;\n' +
|
||||
'attribute vec' + numMatrixDimensions + ' vector;\n' +
|
||||
'void main(void) { gl_Position = vec4(vector*matrix';
|
||||
// Ensure the vec4 has the correct number of dimensions in order to be assignable
|
||||
// to gl_Position.
|
||||
for (var ii = numMatrixDimensions; ii < 4; ++ii) {
|
||||
strVertexShader += ",0.0";
|
||||
}
|
||||
strVertexShader += ");}\n";
|
||||
return wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
|
||||
}
|
||||
|
||||
// Given a vertex shader, matrix location and vector location, create and link
|
||||
// a program with glFragmentShader and a vertex shader returned by loadVertexShader
|
||||
// attached. Bind the matrix to matrixLocation and the vector to vectorLocation.
|
||||
// Return whether the link was successful.
|
||||
function createAndLinkProgram(glVertexShader, matrixLocation, vectorLocation) {
|
||||
var glProgram = gl.createProgram();
|
||||
gl.bindAttribLocation(glProgram, matrixLocation, 'matrix');
|
||||
gl.bindAttribLocation(glProgram, vectorLocation, 'vector');
|
||||
gl.attachShader(glProgram, glVertexShader);
|
||||
gl.attachShader(glProgram, glFragmentShader);
|
||||
gl.linkProgram(glProgram);
|
||||
return gl.getProgramParameter(glProgram, gl.LINK_STATUS);
|
||||
}
|
||||
|
||||
// For each matrix dimension (mat2, mat3 and mat4)
|
||||
for (var mm = 2; mm <= 4; ++mm) {
|
||||
debug('Testing ' + mm + ' dimensional matrices');
|
||||
var glVertexShader = loadVertexShader(mm);
|
||||
// Per the WebGL spec: "LinkProgram will fail if the attribute bindings assigned
|
||||
// by bindAttribLocation do not leave enough space to assign a location for an
|
||||
// active matrix attribute which requires multiple contiguous generic attributes."
|
||||
// We will test this by placing the vector after the matrix attribute such that there
|
||||
// is not enough room for the matrix. Vertify the link operation fails.
|
||||
|
||||
// Run the test for each available attribute slot. Go to maxAttributes-mm to leave enough room
|
||||
// for the matrix itself. Leave another slot open for the vector following the matrix.
|
||||
for (var pp = 0; pp <= maxAttributes - mm - 1; ++pp) {
|
||||
// For each matrix dimension, bind the vector right after the matrix such that we leave
|
||||
// insufficient room for the matrix. Verify doing this will fail the link operation.
|
||||
for (var ll = 0; ll < mm; ++ll) {
|
||||
var vectorLocation = pp + ll;
|
||||
assertMsg(!createAndLinkProgram(glVertexShader, /*matrixLocation*/pp, vectorLocation),
|
||||
"Matrix with location " + pp + " and vector with location " + vectorLocation + " should not link.");
|
||||
}
|
||||
// Ensure that once we have left enough room for the matrix, the program links successfully.
|
||||
var vectorLocation = pp + ll;
|
||||
assertMsg(createAndLinkProgram(glVertexShader, /*matrixLocation*/pp, vectorLocation),
|
||||
"Matrix with location " + pp + " and vector with location " + vectorLocation + " should link.");
|
||||
debug('');
|
||||
}
|
||||
debug('');
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,91 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Repeated BindAttribLocation Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50">
|
||||
</canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test repeated loading of programs involving bindAttribLocation calls");
|
||||
debug("Regression test for <a href='https://code.google.com/p/chromium/issues/detail?id=510637'>crbug.com/510637</a>");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var g_program;
|
||||
var g_attribLocation;
|
||||
function setup(attribIndex) {
|
||||
var program = wtu.setupProgram(
|
||||
gl, ['vshader', 'fshader'], ['vPosition'], [attribIndex]);
|
||||
g_program = program;
|
||||
g_attribLocation = attribIndex;
|
||||
shouldBe("gl.getAttribLocation(g_program, 'vPosition')", "g_attribLocation");
|
||||
return program;
|
||||
}
|
||||
|
||||
var p0 = setup(0);
|
||||
var p3 = setup(3);
|
||||
var p1 = setup(1);
|
||||
// This call fails the getAttribLocation check on some drivers when
|
||||
// Chrome's program binary cache is enabled. On the affected drivers,
|
||||
// it returns the bound attribute location from the first binary
|
||||
// created. Swapping 0 and 1 above will cause it to return 1 rather
|
||||
// than 0.
|
||||
p3 = setup(3);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,102 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Disabled Vertex Attrib Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50">
|
||||
</canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 a_position;
|
||||
attribute vec4 a_color;
|
||||
varying vec4 v_color;
|
||||
bool isCorrectColor(vec4 v) {
|
||||
return v.x == 0.0 && v.y == 0.0 && v.z == 0.0 && v.w == 1.0;
|
||||
}
|
||||
void main() {
|
||||
gl_Position = a_position;
|
||||
v_color = isCorrectColor(a_color) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec4 v_color;
|
||||
void main() {
|
||||
gl_FragColor = v_color;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
description();
|
||||
|
||||
var gl = wtu.create3DContext("example");
|
||||
|
||||
var numVertexAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
for (var ii = 0; ii < numVertexAttribs; ++ii) {
|
||||
var colorLocation = (ii + 1) % numVertexAttribs;
|
||||
var positionLocation = colorLocation ? 0 : 1;
|
||||
|
||||
if (positionLocation != 0) {
|
||||
// We need to create a new 3d context for testing attrib 0
|
||||
// since we've already effected attrib 0 on other tests.
|
||||
gl = wtu.create3DContext();
|
||||
}
|
||||
|
||||
debug("testing attrib: " + colorLocation);
|
||||
var program = wtu.setupProgram(
|
||||
gl,
|
||||
['vshader', 'fshader'],
|
||||
['a_position', 'a_color'],
|
||||
[positionLocation, colorLocation]);
|
||||
var gridRes = 1;
|
||||
wtu.setupIndexedQuad(gl, gridRes, positionLocation);
|
||||
wtu.clearAndDrawIndexedQuad(gl, gridRes);
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
|
||||
}
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Enable Vertex Attrib Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50">
|
||||
</canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("tests that turning on attribs that have no buffer bound fails to draw");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.enableVertexAttribArray(3);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<title>WebGL Matrix Attribute Conformance Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This tests ensures that matrix attribute locations do not clash with other shader attributes.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
|
||||
// Make sure we have room for at least a mat4.
|
||||
var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
debug('MAX_VERTEX_ATTRIBUTES is ' + maxAttributes);
|
||||
shouldBeGreaterThanOrEqual('maxAttributes', '4');
|
||||
|
||||
var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
|
||||
|
||||
// prepareMatrixProgram creates a program with glFragmentShader as the fragment shader.
|
||||
// The vertex shader has numVector number of vectors and a matrix with numMatrixDimensions
|
||||
// dimensions at location numMatrixPosition in the list of attributes.
|
||||
// Ensures that every vector and matrix is used by the program.
|
||||
// Returns a valid program on successfull link; null on link failure.
|
||||
function prepareMatrixProgram(numVectors, numMatrixDimensions, numMatrixPosition) {
|
||||
// Add the matrix and vector attribute declarations. Declare the vectors
|
||||
// to have the same number of components as the matrix so we can perform
|
||||
// operations on them when we assign to gl_Position later on.
|
||||
var strVertexShader = "";
|
||||
for (var ii = 1; ii <= numVectors; ++ii) {
|
||||
if (numMatrixPosition === ii) {
|
||||
strVertexShader += "attribute mat" + numMatrixDimensions + " matrix;\n";
|
||||
}
|
||||
strVertexShader += "attribute vec" + numMatrixDimensions + " vec_" + ii + ";\n";
|
||||
}
|
||||
// numMatrixPosition will be one past numVectors if the caller wants it to be
|
||||
// last. Hence, we need this check outside the loop as well as inside.
|
||||
if (numMatrixPosition === ii) {
|
||||
strVertexShader += "attribute mat" + numMatrixDimensions + " matrix;\n";
|
||||
}
|
||||
// Add the body of the shader. Add up all of the vectors and multiply by the matrix.
|
||||
// The operations we perform do not matter. We just need to ensure that all the vector and
|
||||
// matrix attributes are used.
|
||||
strVertexShader += "void main(void) { \ngl_Position = vec4((";
|
||||
for (var ii = 1; ii <= numVectors; ++ii) {
|
||||
if (ii > 1) {
|
||||
strVertexShader += "+"
|
||||
}
|
||||
strVertexShader += "vec_" + ii;
|
||||
}
|
||||
strVertexShader += ")*matrix";
|
||||
// Ensure the vec4 has the correct number of dimensions in order to be assignable
|
||||
// to gl_Position.
|
||||
for (var ii = numMatrixDimensions; ii < 4; ++ii) {
|
||||
strVertexShader += ",0.0";
|
||||
}
|
||||
strVertexShader += ");}\n";
|
||||
// Load the shader, attach it to a program, and return the link results
|
||||
var glVertexShader = wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
|
||||
var strTest = 'Load shader with ' + numVectors + ' vectors and 1 matrix';
|
||||
if (glVertexShader !== null) {
|
||||
testPassed(strTest);
|
||||
|
||||
var glProgram = gl.createProgram();
|
||||
gl.attachShader(glProgram, glVertexShader);
|
||||
gl.attachShader(glProgram, glFragmentShader);
|
||||
gl.linkProgram(glProgram);
|
||||
if (gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'linkProgram');
|
||||
return glProgram;
|
||||
}
|
||||
} else {
|
||||
testFailed(strTest);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
debug('');
|
||||
|
||||
// Test mat2, mat3 and mat4.
|
||||
for (var mm = 2; mm <= 4; ++mm) {
|
||||
// Add maxAttribute number of attributes by saving enough room in the attribute
|
||||
// list for a matrix of mm dimensions. All of the other attribute slots will be
|
||||
// filled with vectors.
|
||||
var numVectors = maxAttributes - mm;
|
||||
for (var pp = 1; pp <= numVectors + 1; ++pp) {
|
||||
debug('Test ' + mm + ' dimensional matrix at position ' + pp);
|
||||
var glProgram = prepareMatrixProgram(numVectors, /*numMatrixDimensions*/mm, /*numMatrixPosition*/pp);
|
||||
shouldBeNonNull('glProgram');
|
||||
var attribMatrix = gl.getAttribLocation(glProgram, 'matrix');
|
||||
debug('Matrix is at attribute location ' + attribMatrix);
|
||||
shouldBeTrue('attribMatrix > -1');
|
||||
// Per the spec, when an attribute is a matrix attribute, getAttribLocation
|
||||
// returns the index of the first component of the matrix. The implementation must
|
||||
// leave sufficient room for all the components. Here we ensure none of the vectors
|
||||
// in the shader are assigned attribute locations that belong to the matrix.
|
||||
for (var vv = 1; vv <= numVectors; ++vv) {
|
||||
var strVector = 'vec_' + vv
|
||||
var attribVector = gl.getAttribLocation(glProgram, strVector);
|
||||
debug(strVector + ' is at attribute location ' + attribVector);
|
||||
// Begin with the first attribute location where the matrix begins and ensure
|
||||
// the vector's attribute location is not assigned to the matrix. Loop until
|
||||
// we've checked all of the attribute locations that belong to the matrix.
|
||||
for (var ii = attribMatrix; ii < attribMatrix + mm; ++ii) {
|
||||
var testStr = strVector + ' attribute location: ' + attribVector + '. Should not be ' + ii;
|
||||
if (attribVector !== ii) {
|
||||
testPassed(testStr);
|
||||
} else {
|
||||
testFailed(testStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
debug('');
|
||||
}
|
||||
debug('');
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,112 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script id='vshader' type='x-shader'>
|
||||
attribute vec4 a;
|
||||
attribute vec2 p;
|
||||
void main() {
|
||||
gl_Position = vec4(p.x + a.x + a.y + a.z + a.w, p.y, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script id='fshader' type='x-shader'>
|
||||
precision mediump float;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
function checkRedPortion(gl, w, low, high) {
|
||||
var buf = new Uint8Array(w * w * 4);
|
||||
gl.readPixels(0, 0, w, w, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
var i = 0;
|
||||
for (; i < w; ++i) {
|
||||
if (buf[i * 4 + 0] == 255 && buf[i * 4 + 1] == 0 && buf[i * 4 + 2] == 0 && buf[i * 4 + 3] == 255) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return low <= i && i <= high;
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext('testbed', { preserveDrawingBuffer : true });
|
||||
if (!gl) {
|
||||
testFailed('could not create context');
|
||||
return;
|
||||
}
|
||||
var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['p', 'a'])
|
||||
|
||||
gl.enableVertexAttribArray(gl.p);
|
||||
var pos = gl.createBuffer();
|
||||
pos.type = gl.FLOAT;
|
||||
pos.size = 2;
|
||||
pos.num = 4;
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, pos);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
||||
|
||||
gl.vertexAttribPointer(0, pos.size, pos.type, false, 0, 0);
|
||||
|
||||
debug('Test vertexAttrib[1..4]fv by setting different combinations that add up to 1.5 and use that when rendering.');
|
||||
var vals = [[0.5], [0.1,0.4], [0.2,-0.2,0.5], [-1.0,0.3,0.2,2.0]];
|
||||
|
||||
for (var j = 0; j < 4; ++j) {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl['vertexAttrib' + (j+1) + 'fv'](1, vals[j]);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, pos.num);
|
||||
|
||||
if (checkRedPortion(gl, 50, 50 * 0.7, 50 * 0.8)) {
|
||||
testPassed('Attribute of size ' + (j+1) + ' was set correctly');
|
||||
} else {
|
||||
testFailed('Attribute of size ' + (j+1) + ' was not set correctly');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="testbed" width="50" height="50"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description('Verify that using constant attributes works.');
|
||||
runTest();
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,154 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Enable Vertex Attrib Zero Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50">
|
||||
</canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test some of the issues of the difference between attrib 0 on OpenGL vs WebGL");
|
||||
debug("");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var g_program;
|
||||
var g_attribLocation;
|
||||
function setup(attribIndex) {
|
||||
var program = wtu.setupProgram(
|
||||
gl, ['vshader', 'fshader'], ['vPosition'], [attribIndex]);
|
||||
g_program = program;
|
||||
g_attribLocation = attribIndex;
|
||||
shouldBe("g_attribLocation", "gl.getAttribLocation(g_program, 'vPosition')");
|
||||
return program;
|
||||
}
|
||||
|
||||
function setupVerts(numVerts) {
|
||||
var verts = [
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, -1.0, 0.0
|
||||
];
|
||||
var positions = new Float32Array(numVerts * 3);
|
||||
var indices = new Uint16Array(numVerts);
|
||||
for (var ii = 0; ii < numVerts; ++ii) {
|
||||
var ndx = ii % 6;
|
||||
var dst = ii * 3;
|
||||
var src = ndx * 3;
|
||||
for (var jj = 0; jj < 3; ++jj) {
|
||||
positions[dst + jj] = verts[src + jj];
|
||||
}
|
||||
indices[ii] = ii;
|
||||
}
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
|
||||
var indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
}
|
||||
|
||||
var p0 = setup(0);
|
||||
var p3 = setup(3);
|
||||
setupVerts(60000);
|
||||
|
||||
for (var ii = 0; ii < 5; ++ii) {
|
||||
// test drawing with attrib 0
|
||||
gl.useProgram(p0);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawElements(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0);
|
||||
wtu.glErrorShouldBe(
|
||||
gl, gl.NO_ERROR,
|
||||
"drawing using attrib 0 with 6 verts");
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
|
||||
gl.disableVertexAttribArray(0);
|
||||
|
||||
// test drawing without attrib 0
|
||||
gl.useProgram(p3);
|
||||
gl.enableVertexAttribArray(3);
|
||||
gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 60000);
|
||||
wtu.glErrorShouldBe(
|
||||
gl, gl.NO_ERROR,
|
||||
"drawing using attrib 3 with 60000 verts");
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
|
||||
gl.disableVertexAttribArray(3);
|
||||
|
||||
// This second test of drawing without attrib0 unconvered a bug in chrome
|
||||
// where after the draw without attrib0 the attrib 0 emulation code disabled
|
||||
// attrib 0 and it was never re-enabled so this next draw failed.
|
||||
gl.useProgram(p3);
|
||||
gl.enableVertexAttribArray(3);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawElements(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0);
|
||||
wtu.glErrorShouldBe(
|
||||
gl, gl.NO_ERROR,
|
||||
"drawing using attrib 3 with 60000 verts");
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
|
||||
gl.disableVertexAttribArray(3);
|
||||
}
|
||||
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL vertexAttrib Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="2" height="2"> </canvas>
|
||||
|
||||
<script>
|
||||
var contextVersion = 1;
|
||||
</script>
|
||||
<script src="../../js/tests/gl-vertex-attrib.js"></script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,183 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>vertexattribpointer offsets test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50">
|
||||
There is supposed to be an example drawing here, but it's not important.
|
||||
</canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform vec4 color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
function init()
|
||||
{
|
||||
description("test vertexattribpointer offsets work");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
|
||||
|
||||
var tests = [
|
||||
{ data: new Float32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.FLOAT,
|
||||
componentSize: 4,
|
||||
normalize: false,
|
||||
},
|
||||
{ data: new Float32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.FLOAT,
|
||||
componentSize: 4,
|
||||
normalize: false,
|
||||
},
|
||||
{ data: new Uint16Array([ 0, 32767, 0, 32767, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.SHORT,
|
||||
componentSize: 2,
|
||||
normalize: true,
|
||||
},
|
||||
{ data: new Uint16Array([ 0, 65535, 0, 65535, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.UNSIGNED_SHORT,
|
||||
componentSize: 2,
|
||||
normalize: true,
|
||||
},
|
||||
{ data: new Uint16Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.UNSIGNED_SHORT,
|
||||
componentSize: 2,
|
||||
normalize: false,
|
||||
},
|
||||
{ data: new Uint16Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.SHORT,
|
||||
componentSize: 2,
|
||||
normalize: false,
|
||||
},
|
||||
{ data: new Uint8Array([ 0, 127, 0, 127, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.BYTE,
|
||||
componentSize: 1,
|
||||
normalize: true,
|
||||
},
|
||||
{ data: new Uint8Array([ 0, 255, 0, 255, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.UNSIGNED_BYTE,
|
||||
componentSize: 1,
|
||||
normalize: true,
|
||||
},
|
||||
{ data: new Uint8Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.BYTE,
|
||||
componentSize: 1,
|
||||
normalize: false,
|
||||
},
|
||||
{ data: new Uint8Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
|
||||
type: gl.UNSIGNED_BYTE,
|
||||
componentSize: 1,
|
||||
normalize: false,
|
||||
}
|
||||
];
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
|
||||
var colorLoc = gl.getUniformLocation(program, "color");
|
||||
var kNumVerts = 3;
|
||||
var kNumComponents = 3;
|
||||
|
||||
var count = 0;
|
||||
for (var tt = 0; tt < tests.length; ++tt) {
|
||||
var test = tests[tt];
|
||||
for (var oo = 0; oo < 3; ++oo) {
|
||||
for (var ss = 0; ss < 3; ++ss) {
|
||||
var offset = (oo + 1) * test.componentSize;
|
||||
var color = (count % 2) ? [1, 0, 0, 1] : [0, 1, 0, 1];
|
||||
var stride = test.componentSize * kNumComponents + test.componentSize * ss;
|
||||
debug("");
|
||||
debug("check with " + wtu.glEnumToString(gl, test.type) + " at offset: " + offset + " with stride:" + stride + " normalize: " + test.normalize);
|
||||
gl.uniform4fv(colorLoc, color);
|
||||
var data = new Uint8Array(test.componentSize * kNumVerts * kNumComponents + stride * (kNumVerts - 1));
|
||||
var view = new Uint8Array(test.data.buffer);
|
||||
var size = test.componentSize * kNumComponents;
|
||||
for (var jj = 0; jj < kNumVerts; ++jj) {
|
||||
var off1 = jj * size;
|
||||
var off2 = jj * stride;
|
||||
for (var zz = 0; zz < size; ++zz) {
|
||||
data[off2 + zz] = view[off1 + zz];
|
||||
}
|
||||
}
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, offset, data);
|
||||
gl.vertexAttribPointer(0, 3, test.type, test.normalize, stride, offset);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
|
||||
var buf = new Uint8Array(50 * 50 * 4);
|
||||
gl.readPixels(0, 0, 50, 50, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
|
||||
var black = [0, 0, 0, 0];
|
||||
var other = [color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255];
|
||||
var otherMsg = "should be " + ((count % 2) ? "red" : "green")
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, black, "should be black", 0);
|
||||
wtu.checkCanvasRect(gl, 0, 49, 1, 1, black, "should be black", 0);
|
||||
wtu.checkCanvasRect(gl, 26, 40, 1, 1, other, otherMsg, 0);
|
||||
wtu.checkCanvasRect(gl, 26, 27, 1, 1, other, otherMsg, 0);
|
||||
wtu.checkCanvasRect(gl, 40, 27, 1, 1, other, otherMsg, 0);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,180 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL vertexAttribPointer Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="2" height="2"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test checks vertexAttribPointer behaviors in WebGL.");
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("");
|
||||
debug("Checking gl.vertexAttribPointer.");
|
||||
|
||||
if (!gl.FIXED) {
|
||||
gl.FIXED = 0x140C;
|
||||
}
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(0), gl.STATIC_DRAW);
|
||||
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 4);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||
"vertexAttribPointer should fail if no buffer is bound and `offset` is non-zero.");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
//gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
//gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
|
||||
//wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
// "vertexAttribPointer should succeed if no buffer is bound and `offset` is zero.");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
|
||||
|
||||
if (wtu.getDefault3DContextVersion() < 2) {
|
||||
gl.vertexAttribPointer(0, 1, gl.INT, 0, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||
"vertexAttribPointer should not support INT");
|
||||
gl.vertexAttribPointer(0, 1, gl.UNSIGNED_INT, 0, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||
"vertexAttribPointer should not support UNSIGNED_INT");
|
||||
gl.vertexAttribPointer(0, 1, gl.FIXED, 0, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||
"vertexAttribPointer should not support FIXED");
|
||||
}
|
||||
|
||||
var checkVertexAttribPointer = function(
|
||||
gl, err, reason, size, type, normalize, stride, offset) {
|
||||
gl.vertexAttribPointer(0, size, type, normalize, stride, offset);
|
||||
var succeeded = (err == gl.NO_ERROR);
|
||||
wtu.glErrorShouldBe(gl, err,
|
||||
"gl.vertexAttribPointer(0, " + size +
|
||||
", gl." + wtu.glEnumToString(gl, type) +
|
||||
", " + normalize +
|
||||
", " + stride +
|
||||
", " + offset +
|
||||
") should " + (succeeded ? "succeed " : "fail ") + reason);
|
||||
if (succeeded) {
|
||||
shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_SIZE)', size.toString());
|
||||
shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE)', 'gl.' + wtu.glEnumToString(gl, type));
|
||||
shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED)', normalize.toString());
|
||||
shouldBe('gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE)', stride.toString());
|
||||
shouldBe('gl.getVertexAttribOffset(0, gl.VERTEX_ATTRIB_ARRAY_POINTER)', offset.toString());
|
||||
}
|
||||
}
|
||||
|
||||
var types = [
|
||||
{ type:gl.BYTE, bytesPerComponent: 1 },
|
||||
{ type:gl.UNSIGNED_BYTE, bytesPerComponent: 1 },
|
||||
{ type:gl.SHORT, bytesPerComponent: 2 },
|
||||
{ type:gl.UNSIGNED_SHORT, bytesPerComponent: 2 },
|
||||
{ type:gl.FLOAT, bytesPerComponent: 4 },
|
||||
];
|
||||
|
||||
for (var ii = 0; ii < types.length; ++ii) {
|
||||
var info = types[ii];
|
||||
debug("");
|
||||
for (var size = 1; size <= 4; ++size) {
|
||||
debug("");
|
||||
debug("checking: " + wtu.glEnumToString(gl, info.type) + " with size " + size);
|
||||
var bytesPerElement = size * info.bytesPerComponent;
|
||||
var offsetSet = [
|
||||
0,
|
||||
1,
|
||||
info.bytesPerComponent - 1,
|
||||
info.bytesPerComponent,
|
||||
info.bytesPerComponent + 1,
|
||||
info.bytesPerComponent * 2];
|
||||
for (var jj = 0; jj < offsetSet.length; ++jj) {
|
||||
var offset = offsetSet[jj];
|
||||
for (var kk = 0; kk < offsetSet.length; ++kk) {
|
||||
var stride = offsetSet[kk];
|
||||
var err = gl.NO_ERROR;
|
||||
var reason = ""
|
||||
if (offset % info.bytesPerComponent != 0) {
|
||||
reason = "because offset is bad";
|
||||
err = gl.INVALID_OPERATION;
|
||||
}
|
||||
if (stride % info.bytesPerComponent != 0) {
|
||||
reason = "because stride is bad";
|
||||
err = gl.INVALID_OPERATION;
|
||||
}
|
||||
checkVertexAttribPointer(
|
||||
gl, err, reason, size, info.type, false, stride, offset);
|
||||
}
|
||||
var stride = Math.floor(255 / info.bytesPerComponent) * info.bytesPerComponent;
|
||||
|
||||
if (offset == 0) {
|
||||
checkVertexAttribPointer(
|
||||
gl, gl.NO_ERROR, "at stride limit",
|
||||
size, info.type, false, stride, offset);
|
||||
checkVertexAttribPointer(
|
||||
gl, gl.INVALID_VALUE, "over stride limit",
|
||||
size, info.type, false,
|
||||
stride + info.bytesPerComponent, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
buffer-bind-test.html
|
||||
buffer-data-and-buffer-sub-data.html
|
||||
--min-version 1.0.3 buffer-data-array-buffer-delete.html
|
||||
--min-version 1.0.4 buffer-uninitialized.html
|
||||
--min-version 1.0.2 element-array-buffer-delete-recreate.html
|
||||
index-validation-copies-indices.html
|
||||
index-validation-crash-with-buffer-sub-data.html
|
||||
--min-version 1.0.2 index-validation-large-buffer.html
|
||||
index-validation-verifies-too-many-indices.html
|
||||
index-validation-with-resized-buffer.html
|
||||
index-validation.html
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL BindBuffer conformance test.</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("Checks a buffer can only be bound to 1 target.");
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("");
|
||||
|
||||
var buf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"should be able to bind array buffer.");
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"should be able to unbind array buffer.");
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||
"should get INVALID_OPERATION if attempting to bind array buffer to different target");
|
||||
|
||||
var buf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"should be able to bind element array buffer.");
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"should be able to unbind element array buffer.");
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||
"should get INVALID_OPERATION if attempting to bind element array buffer to different target");
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test bufferData/bufferSubData with or without ArrayBuffer input");
|
||||
|
||||
debug('Regression test for <a href="https://bugs.webkit.org/show_bug.cgi?id=41884">https://bugs.webkit.org/show_bug.cgi?id=41884</a> : <code>Implement bufferData and bufferSubData with ArrayBuffer as input</code>');
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext();
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
bufferDataTest();
|
||||
bufferDataSizesTest();
|
||||
|
||||
bufferSubDataTest();
|
||||
}
|
||||
|
||||
function bufferDataTest() {
|
||||
debug("");
|
||||
debug("Test bufferData without ArrayBuffer input");
|
||||
|
||||
var buf = gl.createBuffer();
|
||||
shouldBeNonNull(buf);
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, 4, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "no buffer bound");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, -4, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
|
||||
"calling bufferData when buffer size is negative should generate INVALID_VALUE");
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, null, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
|
||||
"calling bufferData when BufferDataSource is null should generate INVALID_VALUE");
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, undefined, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
|
||||
"calling bufferData when BufferDataSource is undefined should generate INVALID_VALUE");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
}
|
||||
|
||||
function bufferDataSizesTest() {
|
||||
debug("");
|
||||
debug("Test bufferData overloads");
|
||||
|
||||
// bufferData has an integer overload and an ArrayBuffer overload.
|
||||
// Per the WebIDL spec, the overload resolution algorithm should resolve types as follows:
|
||||
// - If the argument is null or undefined, pick the nullable type, which is ArrayBuffer.
|
||||
// Per the WebGL spec, null should flag INVALID_VALUE.
|
||||
// - If the argument is an ArrayBuffer, then pick the ArrayBuffer overload
|
||||
// - Everything else should pick the numeric overload. This means things like objects, strings,
|
||||
// floating point numbers, arrays of numbers and strings, etc should convert themselves to a number.
|
||||
var bufferDataParams = [
|
||||
{ parameter: 0, expectedBufferSize: 0 },
|
||||
{ parameter: 4, expectedBufferSize: 4 },
|
||||
{ parameter: 5.1, expectedBufferSize: 5 },
|
||||
{ parameter: 5.8, expectedBufferSize: 5 },
|
||||
{ parameter: 5.5, expectedBufferSize: 5 },
|
||||
|
||||
{ parameter: "4", expectedBufferSize: 4 },
|
||||
{ parameter: "5.1", expectedBufferSize: 5 },
|
||||
{ parameter: "5.8", expectedBufferSize: 5 },
|
||||
{ parameter: "5.5", expectedBufferSize: 5 },
|
||||
{ parameter: "0", expectedBufferSize: 0 },
|
||||
|
||||
{ parameter: [42, 64], expectedBufferSize: 0 },
|
||||
{ parameter: [42], expectedBufferSize: 42 },
|
||||
{ parameter: ["42"], expectedBufferSize: 42 },
|
||||
{ parameter: ["42", "64"], expectedBufferSize: 0 },
|
||||
|
||||
{ parameter: new ArrayBuffer(0), expectedBufferSize: 0 },
|
||||
{ parameter: new ArrayBuffer(4), expectedBufferSize: 4 },
|
||||
|
||||
{ parameter: "WebGL Rocks!", expectedBufferSize: 0 },
|
||||
{ parameter: { mystring: "WebGL Rocks!" }, expectedBufferSize: 0 },
|
||||
];
|
||||
|
||||
bufferDataParams.forEach(function (bufferDataParam) {
|
||||
var buffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, bufferDataParam.parameter, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Passing " + bufferDataParam.parameter + " to bufferData");
|
||||
|
||||
shouldEvaluateTo("gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE)", bufferDataParam.expectedBufferSize);
|
||||
});
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
}
|
||||
|
||||
function bufferSubDataTest() {
|
||||
debug("");
|
||||
debug("Test bufferSubData");
|
||||
|
||||
var buf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new ArrayBuffer(1));
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Calling bufferSubData before bufferData should fail");
|
||||
|
||||
gl.bufferData(gl.ARRAY_BUFFER, 128, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
var array = new ArrayBuffer(64);
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, -10, array);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
|
||||
"calling bufferSubData with ArrayBuffer when offset is negative should INVALID_VALUE");
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 65, array);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "buffer overflow");
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, -10, new Float32Array(8));
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
|
||||
"calling bufferSubData with ArrayBufferView when offset is negative should generate INVALID_VALUE");
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 10, array);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"calling bufferSubData with ArrayBuffer should succeed");
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 10, new Float32Array(0));
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"calling bufferSubData with zero-sized ArrayBufferView should succeed");
|
||||
|
||||
// Arguments that are not ArrayBuffers, null or undefined should throw a TypeError exception
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, 42);");
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, 5.5);");
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, \"5.5\");");
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, [4]);");
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, { mynumber: 42});");
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 10, null)");
|
||||
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 10, undefined)");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should generate no GL error");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,82 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test ARRAY_BUFFER deletion when a vertex attrib array with location != 0 is pointing to it and preserveDrawingBuffer is true.");
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
canvas.addEventListener(
|
||||
"webglcontextlost",
|
||||
function(event) {
|
||||
testFailed("Context lost");
|
||||
event.preventDefault();
|
||||
},
|
||||
false);
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext(canvas, {preserveDrawingBuffer: true});
|
||||
shouldBeNonNull("gl");
|
||||
|
||||
var array = new Float32Array([0]);
|
||||
var buf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
var attribLocation = 1;
|
||||
gl.enableVertexAttribArray(attribLocation);
|
||||
gl.vertexAttribPointer(attribLocation, 1, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.deleteBuffer(buf);
|
||||
|
||||
setTimeout(function() {
|
||||
// Wait for possible context loss
|
||||
finishTest();
|
||||
}, 2000);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,125 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<canvas id="canvas" width="1" height="1"></canvas>
|
||||
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute float a_vertex;
|
||||
void main()
|
||||
{
|
||||
gl_Position = a_vertex == 0.0 ? vec4(9, 9, 9, 1) : vec4(0.5, 0.5, 0.5, 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Tests that uninitialized WebGLBuffers are zeroed out");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext(document.getElementById("canvas"));
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_vertex"]);
|
||||
shouldBeTrue("program != null");
|
||||
|
||||
var TEST_LENGTH = 1024;
|
||||
var TEST_BUFSIZE = TEST_LENGTH * 4;
|
||||
var data = new Float32Array(TEST_LENGTH / 4); // this array is zeroed
|
||||
|
||||
var indices = new Uint16Array(TEST_LENGTH);
|
||||
for (var i = 0; i < TEST_LENGTH; i++) {
|
||||
indices[i] = i;
|
||||
}
|
||||
|
||||
gl.clearColor(0, 1, 0, 1);
|
||||
|
||||
function test(initFunction) {
|
||||
var uninitializedBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, uninitializedBuffer);
|
||||
initFunction();
|
||||
|
||||
var elements = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
gl.useProgram(program);
|
||||
var vertexLoc = gl.getAttribLocation(program, "a_vertex");
|
||||
gl.vertexAttribPointer(vertexLoc, 1, gl.FLOAT, gl.FALSE, 0, 0);
|
||||
gl.enableVertexAttribArray(vertexLoc);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error should result from setup");
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawElements(gl.POINTS, TEST_LENGTH, gl.UNSIGNED_SHORT, 0);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 255, 0, 255], "buffer should be initialized to zero");
|
||||
|
||||
gl.deleteBuffer(uninitializedBuffer);
|
||||
}
|
||||
|
||||
var REPETITIONS = 50;
|
||||
|
||||
var j;
|
||||
debug("");
|
||||
debug("testing bufferData(..., size, ...)");
|
||||
for (j = 0; j < REPETITIONS; j++) {
|
||||
test(function() {
|
||||
gl.bufferData(gl.ARRAY_BUFFER, TEST_BUFSIZE, gl.STATIC_DRAW);
|
||||
});
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("testing bufferSubData(..., offset, data) of uninitialized buffer");
|
||||
for (j = 0; j < REPETITIONS; j++) {
|
||||
test(function() {
|
||||
gl.bufferData(gl.ARRAY_BUFFER, TEST_BUFSIZE, gl.STATIC_DRAW);
|
||||
// bufferSubData the second quarter of the buffer
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, TEST_BUFSIZE / 4, data);
|
||||
});
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,92 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Element Array Buffer Deletion and Recreation Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="32" height="32"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
function init()
|
||||
{
|
||||
description();
|
||||
|
||||
// Clear the background with red.
|
||||
var gl = wtu.create3DContext("example");
|
||||
wtu.setupSimpleColorProgram(gl);
|
||||
var color = [0, 255, 0, 255];
|
||||
wtu.setUByteDrawColor(gl, color);
|
||||
|
||||
var vertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
-1, -1,
|
||||
1, -1,
|
||||
-1, 1,
|
||||
1, 1
|
||||
]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Create an element array buffer.
|
||||
var indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3]), gl.STATIC_DRAW);
|
||||
|
||||
// Delete the element array buffer.
|
||||
gl.deleteBuffer(indexBuffer);
|
||||
|
||||
// Create a new element array buffer.
|
||||
indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3]), gl.STATIC_DRAW);
|
||||
|
||||
// Draw with the new element array buffer.
|
||||
// If the geometry is drawn successfully, the fragment shader will color it green.
|
||||
gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_BYTE, 0);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from draw");
|
||||
wtu.checkCanvas(gl, color, "should be green")
|
||||
}
|
||||
|
||||
init();
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,77 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description('Test that client data is always copied during bufferData and bufferSubData calls, because otherwise the data the GL uses to draw may differ from that checked by the index validation code.')
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var context = wtu.create3DContext();
|
||||
var program = wtu.loadStandardProgram(context);
|
||||
|
||||
context.useProgram(program);
|
||||
var vertexObject = context.createBuffer();
|
||||
context.enableVertexAttribArray(0);
|
||||
context.bindBuffer(context.ARRAY_BUFFER, vertexObject);
|
||||
// 4 vertices -> 2 triangles
|
||||
context.bufferData(context.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), context.STATIC_DRAW);
|
||||
context.vertexAttribPointer(0, 3, context.FLOAT, false, 0, 0);
|
||||
|
||||
var indexObject = context.createBuffer();
|
||||
|
||||
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
var indices = new Uint16Array([ 10000, 0, 1, 2, 3, 10000 ]);
|
||||
context.bufferData(context.ELEMENT_ARRAY_BUFFER, indices, context.STATIC_DRAW);
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)");
|
||||
var indexValidationError = wtu.shouldGenerateGLError(context,
|
||||
[context.INVALID_OPERATION, context.NO_ERROR],
|
||||
"context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
indices[0] = 2;
|
||||
indices[5] = 1;
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,61 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description('Verifies that the index validation code which is within bufferSubData does not crash.')
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext();
|
||||
|
||||
var elementBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 256, gl.STATIC_DRAW);
|
||||
var data = new Uint8Array(127);
|
||||
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 63, data);
|
||||
testPassed("bufferSubData, when buffer object was initialized with null, did not crash");
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,79 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description('Tests that index validation for drawElements works with large attribute buffers');
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var context = wtu.create3DContext();
|
||||
var program = wtu.loadStandardProgram(context);
|
||||
|
||||
context.useProgram(program);
|
||||
|
||||
// Create a small index buffer.
|
||||
var indexObject = context.createBuffer();
|
||||
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
var indexArray = new Uint16Array([0, 1, 2]);
|
||||
context.bufferData(context.ELEMENT_ARRAY_BUFFER, indexArray, context.STATIC_DRAW);
|
||||
|
||||
// Create a large attribute buffer.
|
||||
var vertexObject = context.createBuffer();
|
||||
context.enableVertexAttribArray(0);
|
||||
context.bindBuffer(context.ARRAY_BUFFER, vertexObject);
|
||||
context.bufferData(context.ARRAY_BUFFER, new Float32Array(3 * 65536), context.STATIC_DRAW);
|
||||
context.vertexAttribPointer(0, 3, context.FLOAT, false, 0, 0);
|
||||
|
||||
debug("Test large attribute buffer")
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_SHORT, 0)");
|
||||
|
||||
// Enlarge the attribute buffer slightly.
|
||||
debug("Test even larger attribute buffer")
|
||||
context.bufferData(context.ARRAY_BUFFER, new Float32Array(3 * 65536 + 3), context.STATIC_DRAW);
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLES, 3, context.UNSIGNED_SHORT, 0)");
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,73 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description('Tests that index validation for drawElements does not examine too many indices');
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var context = wtu.create3DContext();
|
||||
var program = wtu.loadStandardProgram(context);
|
||||
|
||||
context.useProgram(program);
|
||||
var vertexObject = context.createBuffer();
|
||||
context.enableVertexAttribArray(0);
|
||||
context.bindBuffer(context.ARRAY_BUFFER, vertexObject);
|
||||
// 4 vertices -> 2 triangles
|
||||
context.bufferData(context.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), context.STATIC_DRAW);
|
||||
context.vertexAttribPointer(0, 3, context.FLOAT, false, 0, 0);
|
||||
|
||||
var indexObject = context.createBuffer();
|
||||
|
||||
debug("Test out of range indices")
|
||||
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array([ 10000, 0, 1, 2, 3, 10000 ]), context.STATIC_DRAW);
|
||||
var indexValidationError = wtu.shouldGenerateGLError(context, [context.INVALID_OPERATION, context.NO_ERROR], "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,130 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="1" height="1"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="vs" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
attribute vec4 vColor;
|
||||
varying vec4 color;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
color = vColor;
|
||||
}
|
||||
</script>
|
||||
<script id="fs" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec4 color;
|
||||
void main() {
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description('Test that updating the size of a vertex buffer is properly noticed by the WebGL implementation.')
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var program = wtu.setupProgram(gl, ["vs", "fs"], ["vPosition", "vColor"]);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after initialization");
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
|
||||
[-1,1,0, 1,1,0, -1,-1,0,
|
||||
-1,-1,0, 1,1,0, 1,-1,0]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex setup");
|
||||
|
||||
var texCoordObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
|
||||
[0,0, 1,0, 0,1,
|
||||
0,1, 1,0, 1,1]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(1);
|
||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coord setup");
|
||||
|
||||
// Now resize these buffers because we want to change what we're drawing.
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
-1,1,0, 1,1,0, -1,-1,0, 1,-1,0,
|
||||
-1,1,0, 1,1,0, -1,-1,0, 1,-1,0]), gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex redefinition");
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
0, 255, 0, 255]), gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coordinate / color redefinition");
|
||||
|
||||
var numQuads = 2;
|
||||
var indices = new Uint8Array(numQuads * 6);
|
||||
for (var ii = 0; ii < numQuads; ++ii) {
|
||||
var offset = ii * 6;
|
||||
var quad = (ii == (numQuads - 1)) ? 4 : 0;
|
||||
indices[offset + 0] = quad + 0;
|
||||
indices[offset + 1] = quad + 1;
|
||||
indices[offset + 2] = quad + 2;
|
||||
indices[offset + 3] = quad + 2;
|
||||
indices[offset + 4] = quad + 1;
|
||||
indices[offset + 5] = quad + 3;
|
||||
}
|
||||
var indexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices");
|
||||
gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,140 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Tests that index validation verifies the correct number of indices");
|
||||
|
||||
function sizeInBytes(type) {
|
||||
switch (type) {
|
||||
case gl.BYTE:
|
||||
case gl.UNSIGNED_BYTE:
|
||||
return 1;
|
||||
case gl.SHORT:
|
||||
case gl.UNSIGNED_SHORT:
|
||||
return 2;
|
||||
case gl.INT:
|
||||
case gl.UNSIGNED_INT:
|
||||
case gl.FLOAT:
|
||||
return 4;
|
||||
default:
|
||||
throw "unknown type";
|
||||
}
|
||||
}
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext();
|
||||
var program = wtu.loadStandardProgram(gl);
|
||||
|
||||
// 3 vertices => 1 triangle, interleaved data
|
||||
var dataComplete = new Float32Array([0, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1, 1,
|
||||
0, 0, 1]);
|
||||
var dataIncomplete = new Float32Array([0, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1, 1]);
|
||||
var indices = new Uint16Array([0, 1, 2]);
|
||||
|
||||
debug("Testing with valid indices");
|
||||
|
||||
var bufferComplete = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, bufferComplete);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, dataComplete, gl.STATIC_DRAW);
|
||||
var elements = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
gl.useProgram(program);
|
||||
var vertexLoc = gl.getAttribLocation(program, "a_vertex");
|
||||
var normalLoc = gl.getAttribLocation(program, "a_normal");
|
||||
gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
|
||||
gl.enableVertexAttribArray(vertexLoc);
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("Testing with out-of-range indices");
|
||||
|
||||
var bufferIncomplete = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, bufferIncomplete);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, dataIncomplete, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
|
||||
gl.enableVertexAttribArray(vertexLoc);
|
||||
gl.disableVertexAttribArray(normalLoc);
|
||||
debug("Enable vertices, valid");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
debug("Enable normals, out-of-range");
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.NO_ERROR]);
|
||||
|
||||
debug("Test with enabled attribute that does not belong to current program");
|
||||
|
||||
gl.disableVertexAttribArray(normalLoc);
|
||||
var extraLoc = Math.max(vertexLoc, normalLoc) + 1;
|
||||
gl.enableVertexAttribArray(extraLoc);
|
||||
debug("Enable an extra attribute with null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||
debug("Enable an extra attribute with insufficient data buffer");
|
||||
gl.vertexAttribPointer(extraLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
debug("Pass large negative index to vertexAttribPointer");
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), -2000000000 * sizeInBytes(gl.FLOAT));
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
buffer-offscreen-test.html
|
||||
buffer-preserve-test.html
|
||||
canvas-test.html
|
||||
canvas-zero-size.html
|
||||
drawingbuffer-static-canvas-test.html
|
||||
--min-version 1.0.2 drawingbuffer-hd-dpi-test.html
|
||||
drawingbuffer-test.html
|
||||
--min-version 1.0.3 draw-webgl-to-canvas-test.html
|
||||
--min-version 1.0.3 draw-static-webgl-to-multiple-canvas-test.html
|
||||
--min-version 1.0.2 framebuffer-bindings-unaffected-on-resize.html
|
||||
--min-version 1.0.4 framebuffer-bindings-affected-by-to-data-url.html
|
||||
--min-version 1.0.3 rapid-resizing.html
|
||||
--min-version 1.0.2 texture-bindings-unaffected-on-resize.html
|
||||
--min-version 1.0.2 to-data-url-test.html
|
||||
viewport-unchanged-upon-resize.html
|
|
@ -0,0 +1,101 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL required buffer clear behaviour test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
height: 3000px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas width="20" height="20" style="border: 1px solid blue;" id="c"></canvas>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
description("This test ensures WebGL implementations correctly clear " +
|
||||
"the drawing buffer on composite if preserveDrawingBuffer is false.");
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl1 = wtu.create3DContext("c");
|
||||
var gl2 = wtu.create3DContext();
|
||||
shouldBeTrue("gl1 != null");
|
||||
shouldBeTrue("gl2 != null");
|
||||
|
||||
shouldBeTrue('gl1.getContextAttributes().preserveDrawingBuffer == false');
|
||||
shouldBeTrue('gl2.getContextAttributes().preserveDrawingBuffer == false');
|
||||
|
||||
function init(gl) {
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
// enable scissor here, before compositing, to make sure it's correctly
|
||||
// ignored and restored
|
||||
gl.scissor(0, 10, 10, 10);
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
}
|
||||
|
||||
init(gl1);
|
||||
init(gl2);
|
||||
|
||||
wtu.waitForComposite(function() {
|
||||
function clear(gl) {
|
||||
// scissor was set earlier
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
clear(gl1);
|
||||
clear(gl2);
|
||||
|
||||
debug("check on screen canvas");
|
||||
wtu.checkCanvasRect(gl1, 0, 10, 10, 10, [0, 0, 255, 255],
|
||||
"cleared corner should be blue, stencil should be preserved");
|
||||
wtu.checkCanvasRect(gl1, 0, 0, 10, 10, [0, 0, 0, 0],
|
||||
"remainder of buffer should be cleared");
|
||||
debug("check off screen canvas");
|
||||
wtu.checkCanvasRect(gl2, 0, 10, 10, 10, [0, 0, 255, 255],
|
||||
"cleared corner should be blue, stencil should be preserved");
|
||||
wtu.checkCanvasRect(gl2, 0, 0, 10, 10, [255, 0, 0, 255],
|
||||
"remainder of buffer should be un-cleared red");
|
||||
|
||||
finishTest();
|
||||
});
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL required buffer clear behaviour test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
height: 3000px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Important to put the canvas at the top so that it's always visible even in the test suite runner.
|
||||
Otherwise it just doesn't get composited in Firefox. -->
|
||||
<canvas width="20" height="20" style="border: 1px solid blue;" id="c"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script type="application/javascript">
|
||||
"use strict";
|
||||
|
||||
description("This test ensures WebGL implementations correctly clear the drawing buffer " +
|
||||
"on composite if preserveDrawingBuffer is false.");
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var gl = wtu.create3DContext("c");
|
||||
shouldBeTrue("gl != null");
|
||||
shouldBeTrue('gl.getContextAttributes().preserveDrawingBuffer == false');
|
||||
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
// enable scissor here, before compositing, to make sure it's correctly
|
||||
// ignored and restored
|
||||
gl.scissor(0, 10, 10, 10);
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
|
||||
function clear() {
|
||||
// scissor was set earlier
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 10, 10, 10, [0, 0, 255, 255],
|
||||
"cleared corner should be blue, stencil should be preserved");
|
||||
wtu.checkCanvasRect(gl, 0, 0, 10, 10, [0, 0, 0, 0],
|
||||
"remainder of buffer should be cleared");
|
||||
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
wtu.waitForComposite(clear);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,214 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Canvas Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<canvas id="canvas2d" width="40" height="40"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
description("This test ensures WebGL implementations interact correctly with the canvas tag.");
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var canvas2d = document.getElementById("canvas2d");
|
||||
var ctx2d = canvas2d.getContext("2d");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("");
|
||||
debug("Checking canvas and WebGL interaction");
|
||||
|
||||
// Check that a canvas with no width or height is 300x150 pixels
|
||||
shouldBe('canvas.width', '300');
|
||||
shouldBe('canvas.height', '150');
|
||||
|
||||
// Check get a 4 value gl parameter as a csv string.
|
||||
var getValue4v = function(name) {
|
||||
var v = gl.getParameter(name);
|
||||
var result = '' +
|
||||
v[0] + ',' +
|
||||
v[1] + ',' +
|
||||
v[2] + ',' +
|
||||
v[3];
|
||||
return result;
|
||||
}
|
||||
|
||||
var getViewport = function() {
|
||||
return getValue4v(gl.VIEWPORT);
|
||||
}
|
||||
|
||||
var getClearColor = function() {
|
||||
return getValue4v(gl.COLOR_CLEAR_VALUE);
|
||||
}
|
||||
|
||||
var isAboutEqual = function(a, b) {
|
||||
return Math.abs(a - b) < 0.01;
|
||||
}
|
||||
|
||||
var isAboutEqualInt = function(a, b) {
|
||||
return Math.abs(a - b) < 3;
|
||||
}
|
||||
|
||||
var checkCanvasContentIs = function(r3d,g3d,b3d,a3d) {
|
||||
var r2d;
|
||||
var g2d;
|
||||
var b2d;
|
||||
var a2d;
|
||||
|
||||
var checkPixel = function(x, y, r3d,g3d,b3d,a3d) {
|
||||
var offset = (y * 40 + x) * 4;
|
||||
r2d = imgData.data[offset];
|
||||
g2d = imgData.data[offset + 1];
|
||||
b2d = imgData.data[offset + 2];
|
||||
a2d = imgData.data[offset + 3];
|
||||
//debug('' + x + ', ' + y + "(" + offset + ") = " + r2d + ", " + g2d + ", " + b2d + ", " + a2d);
|
||||
return isAboutEqualInt(r2d, r3d) &&
|
||||
isAboutEqualInt(g2d, g3d) &&
|
||||
isAboutEqualInt(b2d, b3d) &&
|
||||
isAboutEqualInt(a2d, a3d);
|
||||
}
|
||||
|
||||
var checkPixels = function(r3d,g3d,b3d,a3d) {
|
||||
return checkPixel(0, 0, r3d, g3d, b3d, a3d) &&
|
||||
checkPixel(0, 39, r3d, g3d, b3d, a3d) &&
|
||||
checkPixel(39, 0, r3d, g3d, b3d, a3d) &&
|
||||
checkPixel(39, 39, r3d, g3d, b3d, a3d) &&
|
||||
checkPixel(0, 0, r3d, g3d, b3d, a3d);
|
||||
};
|
||||
|
||||
// Set to just take the color from the 3d canvas
|
||||
ctx2d.globalCompositeOperation = 'copy';
|
||||
|
||||
// fill 2d canvas with orange
|
||||
ctx2d.fillStyle = "rgb(255,192,128)";
|
||||
ctx2d.fillRect (0, 0, 40, 40);
|
||||
|
||||
// get the image data
|
||||
var imgData = ctx2d.getImageData(0, 0, 40, 40);
|
||||
|
||||
// check it got cleared.
|
||||
if (!checkPixels(255, 192, 128, 255)) {
|
||||
testFailed("unable to fill 2d context.");
|
||||
return;
|
||||
}
|
||||
|
||||
// draw 3d canvas on top.
|
||||
ctx2d.drawImage(canvas, 0,0, 40, 40);
|
||||
|
||||
// get the image data
|
||||
var imgData = ctx2d.getImageData(0, 0, 40, 40);
|
||||
|
||||
// Check it's the expected color.
|
||||
if (!checkPixels(r3d, g3d, b3d, a3d)) {
|
||||
testFailed("pixels are " + r2d + "," + g2d + "," + b2d + "," + a2d +
|
||||
" expected " + r3d + "," + g3d + "," + b3d + "," + a3d);
|
||||
} else {
|
||||
testPassed("pixels are " + r3d + "," + g3d + "," + b3d + "," + a3d);
|
||||
}
|
||||
}
|
||||
|
||||
checkCanvasContentIs(0, 0, 0, 0);
|
||||
shouldBe('getViewport()', '"0,0,300,150"');
|
||||
|
||||
// Change the display size of the canvas and check
|
||||
// the viewport size does not change.
|
||||
debug("");
|
||||
debug("change display size of canvas and see that viewport does not change");
|
||||
canvas.style.width = "100px";
|
||||
canvas.style.height = "25px";
|
||||
var intervalId;
|
||||
intervalId = window.setInterval(function() {
|
||||
if (canvas.clientWidth == 100 &&
|
||||
canvas.clientHeight == 25) {
|
||||
window.clearInterval(intervalId);
|
||||
shouldBe('getViewport()', '"0,0,300,150"');
|
||||
shouldBe('canvas.width', '300');
|
||||
shouldBe('canvas.height', '150');
|
||||
|
||||
// Change the actual size of the canvas
|
||||
// Check that the viewport does not change.
|
||||
// Check that the clear color does not change.
|
||||
// Check that the color mask does not change.
|
||||
debug("");
|
||||
debug("change the actual size of the canvas and see that the viewport does not change");
|
||||
gl.clearColor(0.25, 0.5, 0.75, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
checkCanvasContentIs(64, 128, 192, 255);
|
||||
gl.colorMask(0,0,0,0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL errors before resizing the canvas");
|
||||
canvas.width = 400;
|
||||
canvas.height = 10;
|
||||
err = gl.getError();
|
||||
// Some implementations might lost the context when resizing
|
||||
if (err != gl.CONTEXT_LOST_WEBGL) {
|
||||
shouldBe("err", "gl.NO_ERROR");
|
||||
var v = gl.getParameter(gl.COLOR_CLEAR_VALUE);
|
||||
assertMsg(isAboutEqual(v[0], 0.25) &&
|
||||
isAboutEqual(v[1], 0.5) &&
|
||||
isAboutEqual(v[2], 0.75) &&
|
||||
isAboutEqual(v[3], 1),
|
||||
"gl.clearColor should not change after canvas resize");
|
||||
v = gl.getParameter(gl.COLOR_WRITEMASK);
|
||||
assertMsg(isAboutEqual(v[0], 0) &&
|
||||
isAboutEqual(v[1], 0) &&
|
||||
isAboutEqual(v[2], 0) &&
|
||||
isAboutEqual(v[3], 0),
|
||||
"gl.colorMask should not change after canvas resize");
|
||||
shouldBe('getViewport()', '"0,0,300,150"');
|
||||
checkCanvasContentIs(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
debug("");
|
||||
finishTest();
|
||||
}
|
||||
}, 1000/30);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,66 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Zero Size Canvas Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("Tests that a zero size canvas does not fail.");
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.createElement('canvas');
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
canvas.width = 0;
|
||||
canvas.height = 0;
|
||||
gl.viewport(0, 0, 0, 0);
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
shouldBeTrue("program != null");
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
var pixel = new Uint8Array([0, 255, 0, 255]);
|
||||
gl.texImage2D(
|
||||
gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,98 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Canvas Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas2d_0" width="128" height="128"> </canvas>
|
||||
<canvas id="canvas2d_1" width="400" height="400"> </canvas>
|
||||
<canvas id="canvas2d_2" width="128" height="128"> </canvas>
|
||||
<canvas id="webgl" width="400" height="400"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
description("This test ensures WebGL implementations interact correctly with the canvas 2D drawImage call when drawing the same content.");
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var canvas2d = [];
|
||||
var ctx2d = [];
|
||||
for (var i = 0; i < 3; i ++) {
|
||||
canvas2d[i] = document.getElementById("canvas2d_" + i);
|
||||
ctx2d[i] = canvas2d[i].getContext("2d");
|
||||
}
|
||||
|
||||
var canvas = document.getElementById("webgl");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("Checking drawing the same WebGL content to HW accelerated canvas and SW Canvases");
|
||||
debug("");
|
||||
var color = [[0.25, 0.5, 0.75, 1], [1, 0, 0, 1], [1, 0, 1, 1]];
|
||||
var colorValue = [[64, 128, 192, 255], [255, 0, 0, 255], [255, 0, 255, 255]];
|
||||
for (var count = 0; count < 10; count ++) {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
gl.clearColor(color[i][0], color[i][1], color[i][2], color[i][3]);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
ctx2d[0].drawImage(canvas, 0, 0, canvas2d[0].width, canvas2d[0].height);
|
||||
ctx2d[1].drawImage(canvas, 0, 0, canvas2d[1].width, canvas2d[1].height);
|
||||
ctx2d[2].drawImage(canvas, 0, 0, canvas2d[2].width, canvas2d[2].height);
|
||||
wtu.checkCanvasRect(ctx2d[0], 0, 0, canvas2d[0].width, canvas2d[0].height, colorValue[i],
|
||||
"drawImage: Should be (" + colorValue[i][0] + "," + colorValue[i][1] +
|
||||
"," + colorValue[i][2] + "," + colorValue[i][3] + ").", 2);
|
||||
wtu.checkCanvasRect(ctx2d[1], 0, 0, canvas2d[1].width, canvas2d[1].height, colorValue[i],
|
||||
"drawImage: Should be (" + colorValue[i][0] + "," + colorValue[i][1] +
|
||||
"," + colorValue[i][2] + "," + colorValue[i][3] + ").", 2);
|
||||
wtu.checkCanvasRect(ctx2d[2], 0, 0, canvas2d[2].width, canvas2d[2].height, colorValue[i],
|
||||
"drawImage: Should be (" + colorValue[i][0] + "," + colorValue[i][1] +
|
||||
"," + colorValue[i][2] + "," + colorValue[i][3] + ").", 2);
|
||||
}
|
||||
}
|
||||
|
||||
err = gl.getError();
|
||||
debug("");
|
||||
finishTest();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,101 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Canvas Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas2d_0" width="400" height="400"> </canvas>
|
||||
<canvas id="canvas2d_1" width="400" height="400"> </canvas>
|
||||
<canvas id="canvas2d_2" width="400" height="400"> </canvas>
|
||||
<canvas id="webgl" width="400" height="400"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
description("This test ensures WebGL implementations interact correctly with the canvas 2D drawImage call.");
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var canvas2d = [];
|
||||
var ctx2d = [];
|
||||
for (var i = 0; i < 3; i ++) {
|
||||
canvas2d[i] = document.getElementById("canvas2d_" + i);
|
||||
ctx2d[i] = canvas2d[i].getContext("2d");
|
||||
}
|
||||
|
||||
var canvas = document.getElementById("webgl");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("");
|
||||
debug("Checking canvas and WebGL drawImage interaction");
|
||||
for (var count = 0; count < 10; count ++) {
|
||||
gl.clearColor(0.25, 0.5, 0.75, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
ctx2d[0].drawImage(canvas, 0, 0, canvas2d[0].width, canvas2d[0].height);
|
||||
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
ctx2d[1].drawImage(canvas, 0, 0, canvas2d[1].width, canvas2d[1].height);
|
||||
|
||||
gl.clearColor(1, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
ctx2d[2].drawImage(canvas, 0, 0, canvas2d[2].width, canvas2d[2].height);
|
||||
|
||||
gl.clearColor(1, 1, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
wtu.checkCanvasRect(ctx2d[0], 0, 0, canvas2d[0].width, canvas2d[0].height, [64, 128, 192, 255],
|
||||
"drawImage: Should be [64, 128, 192, 255]", 2);
|
||||
wtu.checkCanvasRect(ctx2d[1], 0, 0, canvas2d[1].width, canvas2d[1].height, [255, 0, 0, 255],
|
||||
"drawImage: Should be [255, 0, 0, 255]", 2);
|
||||
wtu.checkCanvasRect(ctx2d[2], 0, 0, canvas2d[2].width, canvas2d[2].height, [255, 0, 255, 255],
|
||||
"drawImage: Should be [255, 0, 255, 255]", 2);
|
||||
}
|
||||
|
||||
err = gl.getError();
|
||||
debug("");
|
||||
finishTest();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,227 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL DrawingBuffer dimensions on HD-DPI machines test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshaderGrid" type="x-shader/x-vertex">
|
||||
attribute vec4 a_position;
|
||||
void main()
|
||||
{
|
||||
gl_Position = a_position;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshaderGrid" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
void main()
|
||||
{
|
||||
float r = mod(gl_FragCoord.x, 2.0) < 1.0 ? 0.0 : 1.0;
|
||||
float g = mod(gl_FragCoord.y, 2.0) < 1.0 ? 0.0 : 1.0;
|
||||
gl_FragColor = vec4(r, g, 0, 1);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description();
|
||||
debug("");
|
||||
|
||||
var gl;
|
||||
var canvas;
|
||||
|
||||
function checkDimensions() {
|
||||
// We expect that for the sizes being testing drawingBufferWidth and drawingBufferHeight
|
||||
// will match canvas.width and canvas.height.
|
||||
|
||||
// We need to test that devicePixelRatio does not effect the backbuffer size of a canvas.
|
||||
shouldBe('gl.drawingBufferWidth', 'canvas.width');
|
||||
shouldBe('gl.drawingBufferHeight', 'canvas.height');
|
||||
}
|
||||
|
||||
// This uses gl_FragCoord to draw a device pixel relavent pattern.
|
||||
// If drawBufferWidth or drawBufferHeight are not in device pixels
|
||||
// this test should fail.
|
||||
function checkGrid(gl, width, height) {
|
||||
var program = wtu.setupProgram(gl, ["vshaderGrid", "fshaderGrid"], ["a_position"]);
|
||||
wtu.setupUnitQuad(gl);
|
||||
gl.useProgram(program);
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
|
||||
var pixels = new Uint8Array(width * height * 4);
|
||||
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
||||
|
||||
var colors = [
|
||||
[ { color: [0, 0, 0, 255], name: "black" }, { color: [255, 0, 0, 255], name: "red" } ],
|
||||
[ { color: [0, 255, 0, 255], name: "green" }, { color: [255, 255, 0, 255], name: "yellow" } ],
|
||||
];
|
||||
|
||||
for (var yy = 0; yy < height; ++yy) {
|
||||
for (var xx = 0; xx < width; ++xx) {
|
||||
var info = colors[yy % 2][xx % 2];
|
||||
var color = info.color;
|
||||
var offset = (yy * width + xx) * 4;
|
||||
for (var jj = 0; jj < 4; ++jj) {
|
||||
if (pixels[offset + jj] != color[jj]) {
|
||||
var actual = [pixels[offset], pixels[offset + 1], pixels[offset + 2], pixels[offset + 3]];
|
||||
testFailed("at " + xx + ", " + yy + " expected " + color + "(" + info.name + ") was " + actual);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
testPassed("grid rendered correctly");
|
||||
}
|
||||
|
||||
// This passes device coordinate vertices in to make sure gl.viewport is not being mucked with.
|
||||
function checkQuad(gl, width, height) {
|
||||
var deviceToClipSpace = function(value, range) {
|
||||
return value / range * 2 - 1;
|
||||
}
|
||||
|
||||
var program = wtu.setupColorQuad(gl);
|
||||
|
||||
// draw a small green square in the top right corner.
|
||||
var deviceX1 = width - 4;
|
||||
var deviceX2 = width;
|
||||
var deviceY1 = height - 4;
|
||||
var deviceY2 = height;
|
||||
|
||||
var clipX1 = deviceToClipSpace(deviceX1, width);
|
||||
var clipX2 = deviceToClipSpace(deviceX2, width);
|
||||
var clipY1 = deviceToClipSpace(deviceY1, height);
|
||||
var clipY2 = deviceToClipSpace(deviceY2, height);
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
new Float32Array(
|
||||
[ clipX2, clipY2,
|
||||
clipX1, clipY2,
|
||||
clipX1, clipY1,
|
||||
clipX2, clipY2,
|
||||
clipX1, clipY1,
|
||||
clipX2, clipY1]),
|
||||
gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
var green = [0, 255, 0, 255];
|
||||
var black = [0, 0, 0, 0];
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.drawUByteColorQuad(gl, [0, 255, 0, 255]);
|
||||
|
||||
var squareWidth = deviceX2 - deviceX1;
|
||||
var squareHeight = deviceY2 - deviceY1;
|
||||
|
||||
// check the square.
|
||||
wtu.checkCanvasRect(gl, deviceX1, deviceY1, squareWidth, squareHeight, green, "should be green");
|
||||
// check outside the square.
|
||||
wtu.checkCanvasRect(gl, 0, 0, width, height - squareHeight, black, "should be black");
|
||||
wtu.checkCanvasRect(gl, 0, height - squareHeight, width - squareWidth, squareHeight, black, "should be black");
|
||||
}
|
||||
|
||||
|
||||
function test(desiredWidth, desiredHeight) {
|
||||
debug("");
|
||||
debug("testing canvas width = " + desiredWidth + ", height = " + desiredHeight);
|
||||
|
||||
// Make a fresh canvas.
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.width = desiredWidth;
|
||||
canvas.height = desiredHeight;
|
||||
|
||||
// This 'gl' must be global for shouldBe to work.
|
||||
gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
// Check the dimensions are correct.
|
||||
checkDimensions();
|
||||
|
||||
// Draw a pixel grid using a shader that draws in device coordinates
|
||||
checkGrid(gl, desiredWidth, desiredHeight);
|
||||
|
||||
// Draw a quad in the top right corner.
|
||||
checkQuad(gl, desiredWidth, desiredHeight);
|
||||
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
|
||||
debug("");
|
||||
debug("testing resizing canvas to width = " + desiredWidth + ", height = " + desiredHeight);
|
||||
|
||||
var oldViewport = gl.getParameter(gl.VIEWPORT);
|
||||
|
||||
// flip width and height
|
||||
canvas.width = desiredHeight;
|
||||
canvas.height = desiredWidth;
|
||||
|
||||
// fix the viewport
|
||||
gl.viewport(0, 0, desiredHeight, desiredWidth);
|
||||
|
||||
// Check the dimensions are correct.
|
||||
checkDimensions();
|
||||
|
||||
// Draw a pixel grid using a shader that draws in device coordinates
|
||||
checkGrid(gl, desiredHeight, desiredWidth);
|
||||
|
||||
// Draw a quad in the top right corner.
|
||||
checkQuad(gl, desiredHeight, desiredWidth);
|
||||
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
}
|
||||
}
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
// test a few sizes
|
||||
test(32, 16);
|
||||
test(128, 64);
|
||||
test(256, 512);
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,139 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Canvas Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="50" height="50"> </canvas>
|
||||
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
function drawTriangleTest(gl)
|
||||
{
|
||||
var width = 50;
|
||||
var height = 50;
|
||||
gl.viewport(0, 0, width, height);
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
|
||||
// Test several locations
|
||||
wtu.checkCanvasRect(gl, 0, 0, width, 1, [0, 0, 0, 255],
|
||||
'First line should be all black');
|
||||
wtu.checkCanvasRect(gl, 20, 15, 10, 1, [255, 0, 0, 255],
|
||||
'Line 15 should be red for at least 10 red pixels starting 20 pixels in');
|
||||
wtu.checkCanvasRect(gl, 0, height - 1, width, 1, [0, 0, 0, 255],
|
||||
'Last line should be all black');
|
||||
}
|
||||
|
||||
description("This test ensures WebGL implementations correctly implement drawingbufferWidth/Height with compositing.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var err;
|
||||
var maxSize;
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
|
||||
shouldBeNonNull("program");
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.clearColor(0, 0, 0, 1);
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
|
||||
debug("");
|
||||
debug("Checking drawingBufferWidth/drawingBufferHeight");
|
||||
|
||||
shouldBe('gl.drawingBufferWidth', 'gl.canvas.width');
|
||||
shouldBe('gl.drawingBufferHeight', 'gl.canvas.height');
|
||||
|
||||
// Check that changing the canvas size to something too large falls back to reasonable values.
|
||||
maxSize = gl.getParameter(gl.MAX_VIEWPORT_DIMS);
|
||||
shouldBeTrue('maxSize[0] > 0');
|
||||
shouldBeTrue('maxSize[1] > 0');
|
||||
|
||||
// debug("MAX_VIEWPORT_DIMS = " + maxSize[0] + "x" + maxSize[1]);
|
||||
gl.canvas.width = maxSize[0] * 4;
|
||||
gl.canvas.height = maxSize[1] * 4;
|
||||
shouldBeTrue('gl.drawingBufferWidth > 0');
|
||||
shouldBeTrue('gl.drawingBufferHeight > 0');
|
||||
shouldBeTrue('gl.drawingBufferWidth <= maxSize[0]');
|
||||
shouldBeTrue('gl.drawingBufferHeight <= maxSize[1]');
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
|
||||
debug("");
|
||||
debug("Checking scaling up then back down to 50/50, drawing still works.");
|
||||
gl.canvas.width = 50;
|
||||
gl.canvas.height = 50;
|
||||
shouldBeTrue('gl.drawingBufferWidth == 50');
|
||||
shouldBeTrue('gl.drawingBufferHeight == 50');
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
drawTriangleTest(gl);
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
}
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,140 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Canvas.drawingBufferWidth,drawingBufferHeight Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description();
|
||||
debug("");
|
||||
|
||||
var gl;
|
||||
var oldViewport;
|
||||
|
||||
function getMaxViewportDimensions() {
|
||||
// create a fresh canvas. This canvas will be discarded
|
||||
// after exiting this function.
|
||||
var canvas = document.createElement("canvas");
|
||||
gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
return [0, 0];
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
// For a default size canvas these should be equal.
|
||||
// WebGL contexts are not allowed to change the size of the drawingBuffer
|
||||
// for things like hi-res displays.
|
||||
shouldBe('gl.drawingBufferWidth', 'gl.canvas.width');
|
||||
shouldBe('gl.drawingBufferHeight', 'gl.canvas.height');
|
||||
return gl.getParameter(gl.MAX_VIEWPORT_DIMS);
|
||||
}
|
||||
}
|
||||
|
||||
function test(desiredWidth, desiredHeight) {
|
||||
debug("");
|
||||
debug("testing canvas width = " + desiredWidth + ", height = " + desiredHeight);
|
||||
|
||||
// Make a fresh canvas.
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = desiredWidth;
|
||||
canvas.height = desiredHeight;
|
||||
|
||||
// This 'gl' must be global for shouldBe to work.
|
||||
gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
// Verify these stats didn't change since they come from a different
|
||||
// context.
|
||||
shouldBe('gl.getParameter(gl.MAX_VIEWPORT_DIMS)[0]', 'maxSize[0]');
|
||||
shouldBe('gl.getParameter(gl.MAX_VIEWPORT_DIMS)[1]', 'maxSize[1]');
|
||||
|
||||
// check the initial viewport matches the drawingBufferWidth and drawingBufferHeight
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[0]', '0');
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[1]', '0');
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[2]', 'gl.drawingBufferWidth');
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[3]', 'gl.drawingBufferHeight');
|
||||
|
||||
debug("");
|
||||
debug("testing resizing canvas to width = " + desiredWidth + ", height = " + desiredHeight);
|
||||
|
||||
oldViewport = gl.getParameter(gl.VIEWPORT);
|
||||
|
||||
// flip width and height
|
||||
canvas.width = desiredHeight;
|
||||
canvas.height = desiredWidth;
|
||||
|
||||
// Verify the viewport didn't change.
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[0]', 'oldViewport[0]');
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[1]', 'oldViewport[1]');
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[2]', 'oldViewport[2]');
|
||||
shouldBe('gl.getParameter(gl.VIEWPORT)[3]', 'oldViewport[3]');
|
||||
|
||||
// fix the viewport
|
||||
// gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
|
||||
shouldBe('gl.getError()', 'gl.NO_ERROR');
|
||||
}
|
||||
}
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var maxSize = getMaxViewportDimensions();
|
||||
debug("MAX_VIEWPORT_DIMS: " + maxSize[0] + ", " + maxSize[1]);
|
||||
|
||||
shouldBeTrue('maxSize[0] > 0');
|
||||
shouldBeTrue('maxSize[1] > 0');
|
||||
|
||||
// test a small size to make sure it works at all.
|
||||
test(16, 32);
|
||||
|
||||
// Make a canvas slightly larger than the max size WebGL can handle.
|
||||
// From section 2.2 of the spec the WebGL implementation should allow this to work.
|
||||
|
||||
// test a size larger than MAX_VIEWPORT_DIMS in both dimensions
|
||||
test(maxSize[0] + 32, 8);
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,97 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2015 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Verifies than GL framebuffer bindings do not change by toDataURL()</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("Verifies than GL framebuffer bindings do not change by toDataURL()");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
function test() {
|
||||
var glCanvas = document.getElementById("example");
|
||||
var gl = wtu.create3DContext(glCanvas, {preserveDrawingBuffer: true, premultipliedAlpha: true});
|
||||
|
||||
var program = wtu.setupColorQuad(gl);
|
||||
|
||||
// Clear backbuffer in red.
|
||||
gl.clearColor(1.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
|
||||
|
||||
var fbo = gl.createFramebuffer();
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 50, 50, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the FBO in green.
|
||||
gl.clearColor(0.0, 1.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// backbuffer is still in red.
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
|
||||
// toDataURL() calls must not bind backbuffer.
|
||||
glCanvas.toDataURL();
|
||||
// Calling twice caused a bug due to wrong cache impl; crbug.com/445848
|
||||
glCanvas.toDataURL();
|
||||
// It must applies to the FBO, not backbuffer.
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// backbuffer must be in red, not green.
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
|
||||
}
|
||||
test();
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,108 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Verifies that GL framebuffer bindings do not change when canvas is resized</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="4" height="4"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
enableJSTestPreVerboseLogging();
|
||||
description("Verifies that GL framebuffer bindings do not change when canvas is resized");
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("example");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var green = [0, 255, 0, 255];
|
||||
var blue = [0, 0, 255, 255];
|
||||
var fboSize = 2;
|
||||
shouldBeTrue("fboSize < canvas.width");
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
var fboTex = gl.createTexture();
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, fboTex);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fboTex, 0);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, fboSize, fboSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
function checkFBO(color, msg) {
|
||||
wtu.checkCanvasRect(gl, 0, 0, fboSize, fboSize, color, msg);
|
||||
wtu.checkCanvasRect(gl, fboSize, fboSize, fboSize, fboSize, [0, 0, 0, 0], "area outside fbo should be transparent black");
|
||||
}
|
||||
|
||||
// The FBO is 2x2 and it's bound so clearing should clear a 2x2 area
|
||||
// and calling read pixels should read the clear color in that 2x2 area
|
||||
// and 0,0,0,0 outside that area.
|
||||
//
|
||||
// If the FBO is no longer bound because of a WebGL implementation error
|
||||
// then likely the clear will clear the backbuffer and reading outside
|
||||
// the 2x2 area will not be 0,0,0,0
|
||||
|
||||
function test() {
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
checkFBO(blue, "should be blue");
|
||||
gl.clearColor(0, 1, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
checkFBO(green, "should be green");
|
||||
}
|
||||
|
||||
debug("test before resizing canvas");
|
||||
test();
|
||||
debug("test after resizing canvas");
|
||||
canvas.width = 8;
|
||||
test();
|
||||
debug("test after resizing canvas and waiting for compositing");
|
||||
canvas.width = 16;
|
||||
wtu.waitForComposite(function() {
|
||||
test();
|
||||
finishTest();
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
|
||||
});
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Rapid Resizing Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas1" style="width: 256px; height: 256px;"> </canvas>
|
||||
<canvas id="canvas2" style="width: 256px; height: 256px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec2 position;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
description("Verifies that rapidly resizing the canvas works correctly.");
|
||||
|
||||
debug("");
|
||||
debug("Regression test for Chromium <a href='http://crbug.com/299371'>Issue 299371</a> and <a href='http://crbug.com/557848'>Issue 557848</a>");
|
||||
debug("");
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas;
|
||||
var largeSize = 256;
|
||||
var smallSize = 128;
|
||||
var currentSize;
|
||||
var gl;
|
||||
var program;
|
||||
var numFrames = 0;
|
||||
var testNumber = 0;
|
||||
|
||||
function nextTest() {
|
||||
++testNumber;
|
||||
numFrames = 0;
|
||||
currentSize = largeSize;
|
||||
if (testNumber > 2) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
canvas = document.getElementById("canvas" + testNumber);
|
||||
canvas.width = currentSize;
|
||||
canvas.height = currentSize;
|
||||
var usePreserveDrawingBuffer = (testNumber == 1) ? true : false;
|
||||
debug("Testing preserveDrawingBuffer = " + usePreserveDrawingBuffer);
|
||||
gl = wtu.create3DContext(canvas, { preserveDrawingBuffer: usePreserveDrawingBuffer });
|
||||
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
gl.clearColor(0, 0, 0, 1);
|
||||
|
||||
program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"]);
|
||||
shouldBeNonNull("program");
|
||||
|
||||
// Prepare to draw quads
|
||||
var quadSize = 0.1;
|
||||
|
||||
var vertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
// Lower left
|
||||
-1, -1 + quadSize,
|
||||
-1, -1,
|
||||
-1 + quadSize, -1,
|
||||
-1 + quadSize, -1 + quadSize,
|
||||
|
||||
// Lower right
|
||||
1 - quadSize, -1 + quadSize,
|
||||
1 - quadSize, -1,
|
||||
1, -1,
|
||||
1, -1 + quadSize,
|
||||
|
||||
// Upper right
|
||||
1 - quadSize, 1,
|
||||
1 - quadSize, 1 - quadSize,
|
||||
1, 1 - quadSize,
|
||||
1, 1,
|
||||
|
||||
// Upper left
|
||||
-1, 1,
|
||||
-1, 1 - quadSize,
|
||||
-1 + quadSize, 1 - quadSize,
|
||||
-1 + quadSize, 1
|
||||
]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
var indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
|
||||
4, 5, 6,
|
||||
4, 6, 7,
|
||||
|
||||
8, 9, 10,
|
||||
8, 10, 11,
|
||||
|
||||
12, 13, 14,
|
||||
12, 14, 15
|
||||
]), gl.STATIC_DRAW);
|
||||
|
||||
wtu.requestAnimFrame(render);
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
if (++numFrames < 30) {
|
||||
if (currentSize == largeSize) {
|
||||
canvas.height = smallSize;
|
||||
currentSize = smallSize;
|
||||
} else {
|
||||
canvas.height = largeSize;
|
||||
currentSize = largeSize;
|
||||
}
|
||||
}
|
||||
|
||||
gl.viewport(0, 0, largeSize, currentSize);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawElements(gl.TRIANGLES, 24, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// Check the four corners
|
||||
var green = [ 0, 255, 0, 255 ];
|
||||
var inset = 3;
|
||||
wtu.checkCanvasRect(gl, inset, inset, 1, 1, green, "lower left should be green", 1);
|
||||
wtu.checkCanvasRect(gl, largeSize - inset, inset, 1, 1, green, "lower right should be green", 1);
|
||||
wtu.checkCanvasRect(gl, inset, currentSize - inset, 1, 1, green, "upper left should be green", 1);
|
||||
wtu.checkCanvasRect(gl, largeSize - inset, currentSize - inset, 1, 1, green, "upper right should be green", 1);
|
||||
|
||||
if (numFrames < 60) {
|
||||
wtu.requestAnimFrame(render);
|
||||
} else {
|
||||
wtu.requestAnimFrame(nextTest);
|
||||
}
|
||||
}
|
||||
|
||||
wtu.requestAnimFrame(nextTest);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,89 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="4" height="4"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description('Verifies that GL texture bindings do not change when canvas is resized');
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("example");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
|
||||
var green = [0, 255, 0, 255];
|
||||
var blue = [0, 0, 255, 255];
|
||||
var tex0 = gl.createTexture();
|
||||
wtu.fillTexture(gl, tex0, 1, 1, blue, 0);
|
||||
gl.activeTexture(gl.TEXTURE1)
|
||||
var tex1 = gl.createTexture();
|
||||
wtu.fillTexture(gl, tex1, 1, 1, green, 0);
|
||||
|
||||
var loc = gl.getUniformLocation(program, "tex");
|
||||
|
||||
function test() {
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
gl.uniform1i(loc, 0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.checkCanvas(gl, blue, "should be blue");
|
||||
gl.uniform1i(loc, 1);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.checkCanvas(gl, green, "should be green");
|
||||
}
|
||||
|
||||
debug("test before resizing canvas");
|
||||
test();
|
||||
debug("test after resizing canvas");
|
||||
canvas.width = 8;
|
||||
test();
|
||||
debug("test after resizing canvas and waiting for compositing");
|
||||
canvas.width = 16;
|
||||
wtu.waitForComposite(function() {
|
||||
test();
|
||||
finishTest();
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
|
||||
});
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL toDataURL test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas width="20" height="20" style="border: 1px solid black; width: 16px; height: 16px" id="c3d"></canvas>
|
||||
<canvas width="20" height="20" style="border: 1px solid black; width: 16px; height: 16px" id="c2d"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script type="application/javascript">
|
||||
var wtu = WebGLTestUtils;
|
||||
var numTests = 10;
|
||||
var gl;
|
||||
var ctx;
|
||||
|
||||
var main = function() {
|
||||
description();
|
||||
ctx = document.getElementById("c2d").getContext("2d");
|
||||
gl = wtu.create3DContext("c3d");
|
||||
|
||||
if (!gl) {
|
||||
testFailed("can't create 3d context");
|
||||
return;
|
||||
}
|
||||
|
||||
var clearRect = function(gl, x, y, width, height, color) {
|
||||
gl.clearColor(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
|
||||
gl.scissor(x, y, width, height);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
};
|
||||
|
||||
var testSize = function(gl, width, height, callback) {
|
||||
debug("testing " + width + " by " + height);
|
||||
gl.canvas.width = width;
|
||||
gl.canvas.height = height;
|
||||
gl.viewport(0, 0, width, height);
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
|
||||
var bottomColor = [255, 0, 0, 255];
|
||||
var topColor = [0, 255, 0, 255];
|
||||
var rightColor = [0, 0, 255, 255];
|
||||
var halfHeight = Math.floor(height / 2);
|
||||
var topHeight = height - halfHeight;
|
||||
var canvasTopHeight = height - topHeight;
|
||||
clearRect(gl, 0, 0, width, halfHeight, bottomColor);
|
||||
clearRect(gl, 0, halfHeight, width, topHeight, topColor);
|
||||
clearRect(gl, width - 1, 0, 1, height, rightColor);
|
||||
|
||||
// Performs gl.canvas.toDataURL() internally
|
||||
var img = wtu.makeImageFromCanvas(gl.canvas, function() {
|
||||
ctx.canvas.width = width;
|
||||
ctx.canvas.height = height;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
ctx.drawImage(img, 0, 0);
|
||||
wtu.checkCanvasRect(ctx, 0, 0, width - 1, topHeight, topColor);
|
||||
wtu.checkCanvasRect(ctx, 0, topHeight, width - 1, halfHeight, bottomColor);
|
||||
wtu.checkCanvasRect(ctx, width - 1, 0, 1, height, rightColor);
|
||||
debug("");
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
var tests = [
|
||||
{ width: 16 , height: 16 , },
|
||||
{ width: 16 - 1, height: 16 , },
|
||||
{ width: 16 - 1, height: 16 - 1, },
|
||||
{ width: 16 + 1, height: 16 - 1, },
|
||||
{ width: 16 - 1, height: 16 + 1, },
|
||||
{ width: 256 , height: 256 , },
|
||||
{ width: 256 - 1, height: 256 , },
|
||||
{ width: 256 - 1, height: 256 - 1, },
|
||||
{ width: 256 + 1, height: 256 - 1, },
|
||||
{ width: 256 - 1, height: 256 + 1, },
|
||||
{ width: 512 , height: 512 , },
|
||||
{ width: 512 - 1, height: 512 , },
|
||||
{ width: 512 - 1, height: 512 - 1, },
|
||||
{ width: 512 + 1, height: 512 - 1, },
|
||||
{ width: 512 - 1, height: 512 + 1, },
|
||||
];
|
||||
var testIndex = 0;
|
||||
var runNextTest = function() {
|
||||
if (testIndex == tests.length) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
var test = tests[testIndex++];
|
||||
testSize(gl, test.width, test.height, function() {
|
||||
setTimeout(runNextTest, 0);
|
||||
})
|
||||
};
|
||||
runNextTest();
|
||||
};
|
||||
main();
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec3 g_Position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="4" height="4"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description('Verifies that GL viewport does not change when canvas is resized');
|
||||
|
||||
var err;
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["g_Position"]);
|
||||
|
||||
var vertices = new Float32Array([
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, -1.0, 0.0]);
|
||||
var vbo = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Clear and set up
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.useProgram(program);
|
||||
// Draw the triangle pair to the frame buffer
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
|
||||
// Ensure that the frame buffer is red at the sampled pixel
|
||||
wtu.checkCanvasRect(gl, 2, 2, 1, 1, [255, 0, 0, 255]);
|
||||
|
||||
// Now resize the canvas
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL errors before resizing the canvas");
|
||||
var canvas = gl.canvas;
|
||||
canvas.width = 8;
|
||||
canvas.height = 8;
|
||||
err = gl.getError();
|
||||
// Some implementations might lost the context when resizing
|
||||
if (err == gl.CONTEXT_LOST_WEBGL) {
|
||||
testPassed("canvas lost context on resize");
|
||||
} else {
|
||||
shouldBe("err", "gl.NO_ERROR");
|
||||
// Do another render
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
// This time, because we did not change the viewport, it should
|
||||
// still be (0, 0, 4, 4), so only the lower-left quadrant should
|
||||
// have been filled.
|
||||
wtu.checkCanvasRect(gl, 6, 6, 1, 1, [0, 0, 255, 255]);
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
--max-version 1.9.9 constants-and-properties.html
|
||||
--min-version 1.0.2 context-attribute-preserve-drawing-buffer.html
|
||||
context-attributes-alpha-depth-stencil-antialias.html
|
||||
--min-version 1.0.4 context-size-change.html
|
||||
--min-version 1.0.4 context-no-alpha-fbo-with-alpha.html
|
||||
--min-version 1.0.2 --slow context-creation-and-destruction.html
|
||||
--min-version 1.0.3 --slow context-creation.html
|
||||
--min-version 1.0.3 --slow context-eviction-with-garbage-collection.html
|
||||
--min-version 1.0.3 context-hidden-alpha.html
|
||||
--min-version 1.0.2 context-release-upon-reload.html
|
||||
--min-version 1.0.2 context-release-with-workers.html
|
||||
context-lost-restored.html
|
||||
context-lost.html
|
||||
--max-version 1.9.9 context-type-test.html
|
||||
incorrect-context-object-behaviour.html
|
||||
--max-version 1.9.9 methods.html
|
||||
premultiplyalpha-test.html
|
||||
resource-sharing-test.html
|
||||
--min-version 1.0.4 user-defined-properties-on-context.html
|
|
@ -0,0 +1,568 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Constants and Properties Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test ensures that the WebGL context has all the constants and (non-function) properties in the specification.");
|
||||
|
||||
var constants = {
|
||||
/* ClearBufferMask */
|
||||
DEPTH_BUFFER_BIT : 0x00000100,
|
||||
STENCIL_BUFFER_BIT : 0x00000400,
|
||||
COLOR_BUFFER_BIT : 0x00004000,
|
||||
|
||||
/* BeginMode */
|
||||
POINTS : 0x0000,
|
||||
LINES : 0x0001,
|
||||
LINE_LOOP : 0x0002,
|
||||
LINE_STRIP : 0x0003,
|
||||
TRIANGLES : 0x0004,
|
||||
TRIANGLE_STRIP : 0x0005,
|
||||
TRIANGLE_FAN : 0x0006,
|
||||
|
||||
/* AlphaFunction (not supported in ES20) */
|
||||
/* NEVER */
|
||||
/* LESS */
|
||||
/* EQUAL */
|
||||
/* LEQUAL */
|
||||
/* GREATER */
|
||||
/* NOTEQUAL */
|
||||
/* GEQUAL */
|
||||
/* ALWAYS */
|
||||
|
||||
/* BlendingFactorDest */
|
||||
ZERO : 0,
|
||||
ONE : 1,
|
||||
SRC_COLOR : 0x0300,
|
||||
ONE_MINUS_SRC_COLOR : 0x0301,
|
||||
SRC_ALPHA : 0x0302,
|
||||
ONE_MINUS_SRC_ALPHA : 0x0303,
|
||||
DST_ALPHA : 0x0304,
|
||||
ONE_MINUS_DST_ALPHA : 0x0305,
|
||||
|
||||
/* BlendingFactorSrc */
|
||||
/* ZERO */
|
||||
/* ONE */
|
||||
DST_COLOR : 0x0306,
|
||||
ONE_MINUS_DST_COLOR : 0x0307,
|
||||
SRC_ALPHA_SATURATE : 0x0308,
|
||||
/* SRC_ALPHA */
|
||||
/* ONE_MINUS_SRC_ALPHA */
|
||||
/* DST_ALPHA */
|
||||
/* ONE_MINUS_DST_ALPHA */
|
||||
|
||||
/* BlendEquationSeparate */
|
||||
FUNC_ADD : 0x8006,
|
||||
BLEND_EQUATION : 0x8009,
|
||||
BLEND_EQUATION_RGB : 0x8009, /* same as BLEND_EQUATION */
|
||||
BLEND_EQUATION_ALPHA : 0x883D,
|
||||
|
||||
/* BlendSubtract */
|
||||
FUNC_SUBTRACT : 0x800A,
|
||||
FUNC_REVERSE_SUBTRACT : 0x800B,
|
||||
|
||||
/* Separate Blend Functions */
|
||||
BLEND_DST_RGB : 0x80C8,
|
||||
BLEND_SRC_RGB : 0x80C9,
|
||||
BLEND_DST_ALPHA : 0x80CA,
|
||||
BLEND_SRC_ALPHA : 0x80CB,
|
||||
CONSTANT_COLOR : 0x8001,
|
||||
ONE_MINUS_CONSTANT_COLOR : 0x8002,
|
||||
CONSTANT_ALPHA : 0x8003,
|
||||
ONE_MINUS_CONSTANT_ALPHA : 0x8004,
|
||||
BLEND_COLOR : 0x8005,
|
||||
|
||||
/* Buffer Objects */
|
||||
ARRAY_BUFFER : 0x8892,
|
||||
ELEMENT_ARRAY_BUFFER : 0x8893,
|
||||
ARRAY_BUFFER_BINDING : 0x8894,
|
||||
ELEMENT_ARRAY_BUFFER_BINDING : 0x8895,
|
||||
|
||||
STREAM_DRAW : 0x88E0,
|
||||
STATIC_DRAW : 0x88E4,
|
||||
DYNAMIC_DRAW : 0x88E8,
|
||||
|
||||
BUFFER_SIZE : 0x8764,
|
||||
BUFFER_USAGE : 0x8765,
|
||||
|
||||
CURRENT_VERTEX_ATTRIB : 0x8626,
|
||||
|
||||
/* CullFaceMode */
|
||||
FRONT : 0x0404,
|
||||
BACK : 0x0405,
|
||||
FRONT_AND_BACK : 0x0408,
|
||||
|
||||
/* DepthFunction */
|
||||
/* NEVER */
|
||||
/* LESS */
|
||||
/* EQUAL */
|
||||
/* LEQUAL */
|
||||
/* GREATER */
|
||||
/* NOTEQUAL */
|
||||
/* GEQUAL */
|
||||
/* ALWAYS */
|
||||
|
||||
/* EnableCap */
|
||||
/* TEXTURE_2D */
|
||||
CULL_FACE : 0x0B44,
|
||||
BLEND : 0x0BE2,
|
||||
DITHER : 0x0BD0,
|
||||
STENCIL_TEST : 0x0B90,
|
||||
DEPTH_TEST : 0x0B71,
|
||||
SCISSOR_TEST : 0x0C11,
|
||||
POLYGON_OFFSET_FILL : 0x8037,
|
||||
SAMPLE_ALPHA_TO_COVERAGE : 0x809E,
|
||||
SAMPLE_COVERAGE : 0x80A0,
|
||||
|
||||
/* ErrorCode */
|
||||
NO_ERROR : 0,
|
||||
INVALID_ENUM : 0x0500,
|
||||
INVALID_VALUE : 0x0501,
|
||||
INVALID_OPERATION : 0x0502,
|
||||
OUT_OF_MEMORY : 0x0505,
|
||||
|
||||
/* FrontFaceDirection */
|
||||
CW : 0x0900,
|
||||
CCW : 0x0901,
|
||||
|
||||
/* GetPName */
|
||||
LINE_WIDTH : 0x0B21,
|
||||
ALIASED_POINT_SIZE_RANGE : 0x846D,
|
||||
ALIASED_LINE_WIDTH_RANGE : 0x846E,
|
||||
CULL_FACE_MODE : 0x0B45,
|
||||
FRONT_FACE : 0x0B46,
|
||||
DEPTH_RANGE : 0x0B70,
|
||||
DEPTH_WRITEMASK : 0x0B72,
|
||||
DEPTH_CLEAR_VALUE : 0x0B73,
|
||||
DEPTH_FUNC : 0x0B74,
|
||||
STENCIL_CLEAR_VALUE : 0x0B91,
|
||||
STENCIL_FUNC : 0x0B92,
|
||||
STENCIL_FAIL : 0x0B94,
|
||||
STENCIL_PASS_DEPTH_FAIL : 0x0B95,
|
||||
STENCIL_PASS_DEPTH_PASS : 0x0B96,
|
||||
STENCIL_REF : 0x0B97,
|
||||
STENCIL_VALUE_MASK : 0x0B93,
|
||||
STENCIL_WRITEMASK : 0x0B98,
|
||||
STENCIL_BACK_FUNC : 0x8800,
|
||||
STENCIL_BACK_FAIL : 0x8801,
|
||||
STENCIL_BACK_PASS_DEPTH_FAIL : 0x8802,
|
||||
STENCIL_BACK_PASS_DEPTH_PASS : 0x8803,
|
||||
STENCIL_BACK_REF : 0x8CA3,
|
||||
STENCIL_BACK_VALUE_MASK : 0x8CA4,
|
||||
STENCIL_BACK_WRITEMASK : 0x8CA5,
|
||||
VIEWPORT : 0x0BA2,
|
||||
SCISSOR_BOX : 0x0C10,
|
||||
/* SCISSOR_TEST */
|
||||
COLOR_CLEAR_VALUE : 0x0C22,
|
||||
COLOR_WRITEMASK : 0x0C23,
|
||||
UNPACK_ALIGNMENT : 0x0CF5,
|
||||
PACK_ALIGNMENT : 0x0D05,
|
||||
MAX_TEXTURE_SIZE : 0x0D33,
|
||||
MAX_VIEWPORT_DIMS : 0x0D3A,
|
||||
SUBPIXEL_BITS : 0x0D50,
|
||||
RED_BITS : 0x0D52,
|
||||
GREEN_BITS : 0x0D53,
|
||||
BLUE_BITS : 0x0D54,
|
||||
ALPHA_BITS : 0x0D55,
|
||||
DEPTH_BITS : 0x0D56,
|
||||
STENCIL_BITS : 0x0D57,
|
||||
POLYGON_OFFSET_UNITS : 0x2A00,
|
||||
/* POLYGON_OFFSET_FILL */
|
||||
POLYGON_OFFSET_FACTOR : 0x8038,
|
||||
TEXTURE_BINDING_2D : 0x8069,
|
||||
SAMPLE_BUFFERS : 0x80A8,
|
||||
SAMPLES : 0x80A9,
|
||||
SAMPLE_COVERAGE_VALUE : 0x80AA,
|
||||
SAMPLE_COVERAGE_INVERT : 0x80AB,
|
||||
|
||||
/* GetTextureParameter */
|
||||
/* TEXTURE_MAG_FILTER */
|
||||
/* TEXTURE_MIN_FILTER */
|
||||
/* TEXTURE_WRAP_S */
|
||||
/* TEXTURE_WRAP_T */
|
||||
|
||||
COMPRESSED_TEXTURE_FORMATS : 0x86A3,
|
||||
|
||||
/* HintMode */
|
||||
DONT_CARE : 0x1100,
|
||||
FASTEST : 0x1101,
|
||||
NICEST : 0x1102,
|
||||
|
||||
/* HintTarget */
|
||||
GENERATE_MIPMAP_HINT : 0x8192,
|
||||
|
||||
/* DataType */
|
||||
BYTE : 0x1400,
|
||||
UNSIGNED_BYTE : 0x1401,
|
||||
SHORT : 0x1402,
|
||||
UNSIGNED_SHORT : 0x1403,
|
||||
INT : 0x1404,
|
||||
UNSIGNED_INT : 0x1405,
|
||||
FLOAT : 0x1406,
|
||||
|
||||
/* PixelFormat */
|
||||
DEPTH_COMPONENT : 0x1902,
|
||||
ALPHA : 0x1906,
|
||||
RGB : 0x1907,
|
||||
RGBA : 0x1908,
|
||||
LUMINANCE : 0x1909,
|
||||
LUMINANCE_ALPHA : 0x190A,
|
||||
|
||||
/* PixelType */
|
||||
/* UNSIGNED_BYTE */
|
||||
UNSIGNED_SHORT_4_4_4_4 : 0x8033,
|
||||
UNSIGNED_SHORT_5_5_5_1 : 0x8034,
|
||||
UNSIGNED_SHORT_5_6_5 : 0x8363,
|
||||
|
||||
/* Shaders */
|
||||
FRAGMENT_SHADER : 0x8B30,
|
||||
VERTEX_SHADER : 0x8B31,
|
||||
MAX_VERTEX_ATTRIBS : 0x8869,
|
||||
MAX_VERTEX_UNIFORM_VECTORS : 0x8DFB,
|
||||
MAX_VARYING_VECTORS : 0x8DFC,
|
||||
MAX_COMBINED_TEXTURE_IMAGE_UNITS : 0x8B4D,
|
||||
MAX_VERTEX_TEXTURE_IMAGE_UNITS : 0x8B4C,
|
||||
MAX_TEXTURE_IMAGE_UNITS : 0x8872,
|
||||
MAX_FRAGMENT_UNIFORM_VECTORS : 0x8DFD,
|
||||
SHADER_TYPE : 0x8B4F,
|
||||
DELETE_STATUS : 0x8B80,
|
||||
LINK_STATUS : 0x8B82,
|
||||
VALIDATE_STATUS : 0x8B83,
|
||||
ATTACHED_SHADERS : 0x8B85,
|
||||
ACTIVE_UNIFORMS : 0x8B86,
|
||||
ACTIVE_ATTRIBUTES : 0x8B89,
|
||||
SHADING_LANGUAGE_VERSION : 0x8B8C,
|
||||
CURRENT_PROGRAM : 0x8B8D,
|
||||
|
||||
/* StencilFunction */
|
||||
NEVER : 0x0200,
|
||||
LESS : 0x0201,
|
||||
EQUAL : 0x0202,
|
||||
LEQUAL : 0x0203,
|
||||
GREATER : 0x0204,
|
||||
NOTEQUAL : 0x0205,
|
||||
GEQUAL : 0x0206,
|
||||
ALWAYS : 0x0207,
|
||||
|
||||
/* StencilOp */
|
||||
/* ZERO */
|
||||
KEEP : 0x1E00,
|
||||
REPLACE : 0x1E01,
|
||||
INCR : 0x1E02,
|
||||
DECR : 0x1E03,
|
||||
INVERT : 0x150A,
|
||||
INCR_WRAP : 0x8507,
|
||||
DECR_WRAP : 0x8508,
|
||||
|
||||
/* StringName */
|
||||
VENDOR : 0x1F00,
|
||||
RENDERER : 0x1F01,
|
||||
VERSION : 0x1F02,
|
||||
|
||||
/* TextureMagFilter */
|
||||
NEAREST : 0x2600,
|
||||
LINEAR : 0x2601,
|
||||
|
||||
/* TextureMinFilter */
|
||||
/* NEAREST */
|
||||
/* LINEAR */
|
||||
NEAREST_MIPMAP_NEAREST : 0x2700,
|
||||
LINEAR_MIPMAP_NEAREST : 0x2701,
|
||||
NEAREST_MIPMAP_LINEAR : 0x2702,
|
||||
LINEAR_MIPMAP_LINEAR : 0x2703,
|
||||
|
||||
/* TextureParameterName */
|
||||
TEXTURE_MAG_FILTER : 0x2800,
|
||||
TEXTURE_MIN_FILTER : 0x2801,
|
||||
TEXTURE_WRAP_S : 0x2802,
|
||||
TEXTURE_WRAP_T : 0x2803,
|
||||
|
||||
/* TextureTarget */
|
||||
TEXTURE_2D : 0x0DE1,
|
||||
TEXTURE : 0x1702,
|
||||
|
||||
TEXTURE_CUBE_MAP : 0x8513,
|
||||
TEXTURE_BINDING_CUBE_MAP : 0x8514,
|
||||
TEXTURE_CUBE_MAP_POSITIVE_X : 0x8515,
|
||||
TEXTURE_CUBE_MAP_NEGATIVE_X : 0x8516,
|
||||
TEXTURE_CUBE_MAP_POSITIVE_Y : 0x8517,
|
||||
TEXTURE_CUBE_MAP_NEGATIVE_Y : 0x8518,
|
||||
TEXTURE_CUBE_MAP_POSITIVE_Z : 0x8519,
|
||||
TEXTURE_CUBE_MAP_NEGATIVE_Z : 0x851A,
|
||||
MAX_CUBE_MAP_TEXTURE_SIZE : 0x851C,
|
||||
|
||||
/* TextureUnit */
|
||||
TEXTURE0 : 0x84C0,
|
||||
TEXTURE1 : 0x84C1,
|
||||
TEXTURE2 : 0x84C2,
|
||||
TEXTURE3 : 0x84C3,
|
||||
TEXTURE4 : 0x84C4,
|
||||
TEXTURE5 : 0x84C5,
|
||||
TEXTURE6 : 0x84C6,
|
||||
TEXTURE7 : 0x84C7,
|
||||
TEXTURE8 : 0x84C8,
|
||||
TEXTURE9 : 0x84C9,
|
||||
TEXTURE10 : 0x84CA,
|
||||
TEXTURE11 : 0x84CB,
|
||||
TEXTURE12 : 0x84CC,
|
||||
TEXTURE13 : 0x84CD,
|
||||
TEXTURE14 : 0x84CE,
|
||||
TEXTURE15 : 0x84CF,
|
||||
TEXTURE16 : 0x84D0,
|
||||
TEXTURE17 : 0x84D1,
|
||||
TEXTURE18 : 0x84D2,
|
||||
TEXTURE19 : 0x84D3,
|
||||
TEXTURE20 : 0x84D4,
|
||||
TEXTURE21 : 0x84D5,
|
||||
TEXTURE22 : 0x84D6,
|
||||
TEXTURE23 : 0x84D7,
|
||||
TEXTURE24 : 0x84D8,
|
||||
TEXTURE25 : 0x84D9,
|
||||
TEXTURE26 : 0x84DA,
|
||||
TEXTURE27 : 0x84DB,
|
||||
TEXTURE28 : 0x84DC,
|
||||
TEXTURE29 : 0x84DD,
|
||||
TEXTURE30 : 0x84DE,
|
||||
TEXTURE31 : 0x84DF,
|
||||
ACTIVE_TEXTURE : 0x84E0,
|
||||
|
||||
/* TextureWrapMode */
|
||||
REPEAT : 0x2901,
|
||||
CLAMP_TO_EDGE : 0x812F,
|
||||
MIRRORED_REPEAT : 0x8370,
|
||||
|
||||
/* Uniform Types */
|
||||
FLOAT_VEC2 : 0x8B50,
|
||||
FLOAT_VEC3 : 0x8B51,
|
||||
FLOAT_VEC4 : 0x8B52,
|
||||
INT_VEC2 : 0x8B53,
|
||||
INT_VEC3 : 0x8B54,
|
||||
INT_VEC4 : 0x8B55,
|
||||
BOOL : 0x8B56,
|
||||
BOOL_VEC2 : 0x8B57,
|
||||
BOOL_VEC3 : 0x8B58,
|
||||
BOOL_VEC4 : 0x8B59,
|
||||
FLOAT_MAT2 : 0x8B5A,
|
||||
FLOAT_MAT3 : 0x8B5B,
|
||||
FLOAT_MAT4 : 0x8B5C,
|
||||
SAMPLER_2D : 0x8B5E,
|
||||
SAMPLER_CUBE : 0x8B60,
|
||||
|
||||
/* Vertex Arrays */
|
||||
VERTEX_ATTRIB_ARRAY_ENABLED : 0x8622,
|
||||
VERTEX_ATTRIB_ARRAY_SIZE : 0x8623,
|
||||
VERTEX_ATTRIB_ARRAY_STRIDE : 0x8624,
|
||||
VERTEX_ATTRIB_ARRAY_TYPE : 0x8625,
|
||||
VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
|
||||
VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
|
||||
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
|
||||
|
||||
/* Read Format */
|
||||
IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A,
|
||||
IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B,
|
||||
|
||||
/* Shader Source */
|
||||
COMPILE_STATUS : 0x8B81,
|
||||
|
||||
/* Shader Precision-Specified Types */
|
||||
LOW_FLOAT : 0x8DF0,
|
||||
MEDIUM_FLOAT : 0x8DF1,
|
||||
HIGH_FLOAT : 0x8DF2,
|
||||
LOW_INT : 0x8DF3,
|
||||
MEDIUM_INT : 0x8DF4,
|
||||
HIGH_INT : 0x8DF5,
|
||||
|
||||
/* Framebuffer Object. */
|
||||
FRAMEBUFFER : 0x8D40,
|
||||
RENDERBUFFER : 0x8D41,
|
||||
|
||||
RGBA4 : 0x8056,
|
||||
RGB5_A1 : 0x8057,
|
||||
RGB565 : 0x8D62,
|
||||
DEPTH_COMPONENT16 : 0x81A5,
|
||||
STENCIL_INDEX : 0x1901,
|
||||
STENCIL_INDEX8 : 0x8D48,
|
||||
DEPTH_STENCIL : 0x84F9,
|
||||
|
||||
RENDERBUFFER_WIDTH : 0x8D42,
|
||||
RENDERBUFFER_HEIGHT : 0x8D43,
|
||||
RENDERBUFFER_INTERNAL_FORMAT : 0x8D44,
|
||||
RENDERBUFFER_RED_SIZE : 0x8D50,
|
||||
RENDERBUFFER_GREEN_SIZE : 0x8D51,
|
||||
RENDERBUFFER_BLUE_SIZE : 0x8D52,
|
||||
RENDERBUFFER_ALPHA_SIZE : 0x8D53,
|
||||
RENDERBUFFER_DEPTH_SIZE : 0x8D54,
|
||||
RENDERBUFFER_STENCIL_SIZE : 0x8D55,
|
||||
|
||||
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE : 0x8CD0,
|
||||
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME : 0x8CD1,
|
||||
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL : 0x8CD2,
|
||||
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
|
||||
|
||||
COLOR_ATTACHMENT0 : 0x8CE0,
|
||||
DEPTH_ATTACHMENT : 0x8D00,
|
||||
STENCIL_ATTACHMENT : 0x8D20,
|
||||
DEPTH_STENCIL_ATTACHMENT : 0x821A,
|
||||
|
||||
NONE : 0,
|
||||
|
||||
FRAMEBUFFER_COMPLETE : 0x8CD5,
|
||||
FRAMEBUFFER_INCOMPLETE_ATTACHMENT : 0x8CD6,
|
||||
FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : 0x8CD7,
|
||||
FRAMEBUFFER_INCOMPLETE_DIMENSIONS : 0x8CD9,
|
||||
FRAMEBUFFER_UNSUPPORTED : 0x8CDD,
|
||||
|
||||
FRAMEBUFFER_BINDING : 0x8CA6,
|
||||
RENDERBUFFER_BINDING : 0x8CA7,
|
||||
MAX_RENDERBUFFER_SIZE : 0x84E8,
|
||||
|
||||
INVALID_FRAMEBUFFER_OPERATION : 0x0506,
|
||||
|
||||
/* WebGL-specific enums */
|
||||
UNPACK_FLIP_Y_WEBGL : 0x9240,
|
||||
UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
|
||||
CONTEXT_LOST_WEBGL : 0x9242,
|
||||
UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
|
||||
BROWSER_DEFAULT_WEBGL : 0x9244
|
||||
};
|
||||
|
||||
// Other non-function properties on the WebGL object
|
||||
var otherProperties = {
|
||||
drawingBufferWidth : "number",
|
||||
drawingBufferHeight : "number",
|
||||
canvas : "implementation-dependent"
|
||||
};
|
||||
|
||||
// Properties to be ignored (as a list of strings) because they were
|
||||
// added in versions of the spec that are backward-compatible with
|
||||
// this version
|
||||
var ignoredProperties = [
|
||||
];
|
||||
|
||||
// Constants removed from the WebGL spec compared to ES 2.0
|
||||
var removedConstants = {
|
||||
NUM_COMPRESSED_TEXTURE_FORMATS : 0x86A2,
|
||||
FIXED : 0x140C,
|
||||
ACTIVE_UNIFORM_MAX_LENGTH : 0x8B87,
|
||||
ACTIVE_ATTRIBUTE_MAX_LENGTH : 0x8B8A,
|
||||
EXTENSIONS : 0x1F03,
|
||||
INFO_LOG_LENGTH : 0x8B84,
|
||||
SHADER_SOURCE_LENGTH : 0x8B88,
|
||||
SHADER_COMPILER : 0x8DFA,
|
||||
SHADER_BINARY_FORMATS : 0x8DF8,
|
||||
NUM_SHADER_BINARY_FORMATS : 0x8DF9,
|
||||
};
|
||||
|
||||
function assertProperty(v, p) {
|
||||
if (p in v) {
|
||||
return true;
|
||||
} else {
|
||||
testFailed("Property does not exist: " + p)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function assertNoProperty(v, p) {
|
||||
if (p in v) {
|
||||
testFailed("Property is defined and should not be: " + p)
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function assertMsg_(bool, msg) {
|
||||
if (!bool) // show only failures to avoid spamming result list
|
||||
assertMsg(bool, msg);
|
||||
return bool;
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
var canvas = document.getElementById("canvas");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var passed = true;
|
||||
for (var i in constants) {
|
||||
var r = assertProperty(gl, i) && assertMsg_(gl[i] == constants[i], "Property "+i+" value test "+gl[i]+" == "+constants[i]);
|
||||
passed = passed && r;
|
||||
}
|
||||
if (passed) {
|
||||
testPassed("All WebGL constants found to have correct values.");
|
||||
}
|
||||
passed = true;
|
||||
for (var i in removedConstants) {
|
||||
var r = assertNoProperty(gl, i);
|
||||
passed = passed && r;
|
||||
}
|
||||
if (passed) {
|
||||
testPassed("All constants removed from WebGL spec were absent from WebGL context.");
|
||||
}
|
||||
var extended = false;
|
||||
for (var i in gl) {
|
||||
if (constants[i] !== undefined) {
|
||||
// OK; known constant
|
||||
} else if (ignoredProperties.indexOf(i) != -1) {
|
||||
// OK; constant that should be ignored because it was added in a later version of the spec
|
||||
} else if (otherProperties[i] !== undefined &&
|
||||
(otherProperties[i] == "implementation-dependent" || typeof gl[i] == otherProperties[i])) {
|
||||
// OK; known property of known type
|
||||
} else if (typeof gl[i] != "function" && removedConstants[i] === undefined) {
|
||||
if (!extended) {
|
||||
extended = true;
|
||||
testFailed("Also found the following extra properties:");
|
||||
}
|
||||
testFailed(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!extended) {
|
||||
testPassed("No extra properties found on WebGL context.");
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,131 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<style>
|
||||
.pattern {
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
}
|
||||
canvas {
|
||||
width:50px;
|
||||
height:50px;
|
||||
}
|
||||
.square {
|
||||
display:inline-block;
|
||||
width:50px;
|
||||
height:50px;
|
||||
background-color:red;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
function checkResult(ctx1, ctx2, preserve) {
|
||||
var imgData1 = ctx1.getImageData(0,0,1,1);
|
||||
var imgData2 = ctx2.getImageData(0,0,1,1);
|
||||
var correct1 = [255,0,0,255];
|
||||
var correct2 = preserve ? [255,0,0,255] : [0,0,0,255];
|
||||
var ok1 = true;
|
||||
var ok2 = true;
|
||||
for (var p = 0; p < 4; ++p) {
|
||||
if (imgData1.data[p] != correct1[p])
|
||||
ok1 = false;
|
||||
if (imgData2.data[p] != correct2[p])
|
||||
ok2 = false;
|
||||
}
|
||||
if (ok1 && ok2)
|
||||
testPassed('Rendered ok with preserveDrawingBuffer ' + preserve +'.');
|
||||
else
|
||||
testFailed('Did not render ok with preserveDrawingBuffer ' + preserve + '.');
|
||||
if (preserve) {
|
||||
finishTest()
|
||||
} else {
|
||||
runTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
function runTest(preserve) {
|
||||
var c1 = document.getElementById('c' + (preserve * 3 + 1));
|
||||
var c2 = document.getElementById('c' + (preserve * 3 + 2));
|
||||
var c3 = document.getElementById('c' + (preserve * 3 + 3));
|
||||
var ctx1 = c1.getContext('2d');
|
||||
var ctx2 = c2.getContext('2d');
|
||||
var gl = wtu.create3DContext(c3, { alpha:false, preserveDrawingBuffer:preserve });
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
ctx1.drawImage(c3, 0, 0);
|
||||
wtu.waitForComposite(function() {
|
||||
ctx2.drawImage(c3, 0, 0);
|
||||
checkResult(ctx1, ctx2, preserve);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="pattern">
|
||||
<canvas id='c1'></canvas>
|
||||
<canvas id='c2'></canvas>
|
||||
<canvas id='c3'></canvas>
|
||||
</div>
|
||||
<span>should look like</span>
|
||||
<div class="pattern">
|
||||
<div class='square'></div>
|
||||
<div class='square' style='background-color:black'></div>
|
||||
<div class='square'></div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="pattern">
|
||||
<canvas id='c4'></canvas>
|
||||
<canvas id='c5'></canvas>
|
||||
<canvas id='c6'></canvas>
|
||||
</div>
|
||||
<span>should look like</span>
|
||||
<div class="pattern">
|
||||
<div class='square'></div>
|
||||
<div class='square'></div>
|
||||
<div class='square'></div>
|
||||
</div>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description('Verify that preserveDrawingBuffer attribute is honored.');
|
||||
runTest(false);
|
||||
var successfullyParsed = true;
|
||||
shouldBeTrue("successfullyParsed");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,356 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec3 pos;
|
||||
attribute vec4 colorIn;
|
||||
varying vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = colorIn;
|
||||
gl_Position = vec4(pos.xyz, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
varying vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
// These four declarations need to be global for "shouldBe" to see them
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl;
|
||||
var contextAttribs = null;
|
||||
var redChannels = [0, 0, 0];
|
||||
var correctColor = null;
|
||||
var framebuffer;
|
||||
var fbHasColor;
|
||||
var fbHasDepth;
|
||||
var fbHasStencil;
|
||||
|
||||
function init()
|
||||
{
|
||||
description('Verify WebGLContextAttributes are working as specified, including alpha, depth, stencil, antialias, but not premultipliedAlpha');
|
||||
|
||||
runTest();
|
||||
}
|
||||
|
||||
function getWebGL(canvasWidth, canvasHeight, contextAttribs, clearColor, clearDepth, clearStencil)
|
||||
{
|
||||
var canvas = document.createElement("canvas");
|
||||
if (!canvas)
|
||||
return null;
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
|
||||
gl = wtu.create3DContext(canvas, contextAttribs);
|
||||
if (!gl)
|
||||
return null;
|
||||
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["pos", "colorIn"]);
|
||||
if (!program)
|
||||
return null;
|
||||
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.enable(gl.STENCIL_TEST);
|
||||
|
||||
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
gl.clearDepth(clearDepth);
|
||||
gl.clearStencil(clearStencil);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.canvas.width, gl.canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
||||
fbHasStencil = false;
|
||||
fbHasDepth = false;
|
||||
fbHasColor = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
|
||||
if (fbHasColor) {
|
||||
var depthStencil = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencil);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, gl.canvas.width, gl.canvas.height);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencil);
|
||||
fbHasDepth = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
|
||||
if (!fbHasDepth) {
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
|
||||
shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
|
||||
} else {
|
||||
fbHasStencil = true;
|
||||
}
|
||||
}
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
|
||||
|
||||
return gl;
|
||||
}
|
||||
|
||||
function drawAndReadPixel(gl, vertices, colors)
|
||||
{
|
||||
var colorOffset = vertices.byteLength;
|
||||
|
||||
var vbo = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, colorOffset + colors.byteLength, gl.STATIC_DRAW);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, colorOffset, colors);
|
||||
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, true, 0, colorOffset);
|
||||
gl.enableVertexAttribArray(1);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);
|
||||
}
|
||||
|
||||
function testDefault()
|
||||
{
|
||||
debug("Testing default attributes: { stencil:false }");
|
||||
shouldBeNonNull("gl = getWebGL(1, 1, null, [ 0, 0, 0, 0 ], 1, 0)");
|
||||
shouldBeFalse("gl.getContextAttributes().stencil");
|
||||
shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0");
|
||||
}
|
||||
|
||||
function testAlpha(alpha)
|
||||
{
|
||||
debug("Testing alpha = " + alpha);
|
||||
if (alpha) {
|
||||
shouldBeNonNull("gl = getWebGL(1, 1, { alpha: true, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
|
||||
shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8");
|
||||
} else {
|
||||
shouldBeNonNull("gl = getWebGL(1, 1, { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
|
||||
shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) == 0");
|
||||
}
|
||||
shouldBeTrue("gl.getParameter(gl.RED_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.GREEN_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.BLUE_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0");
|
||||
shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0");
|
||||
|
||||
shouldBeNonNull("contextAttribs = gl.getContextAttributes()");
|
||||
shouldBeTrue("contextAttribs.alpha == " + alpha);
|
||||
|
||||
var correctColor = (contextAttribs.alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, correctColor);
|
||||
|
||||
if (fbHasColor) {
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
gl.clearColor(0.5, 0.5, 0.5, 0.5);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [127, 127, 127, 127], undefined, 1);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
}
|
||||
|
||||
function testDepth(depth)
|
||||
{
|
||||
debug("Testing depth = " + depth);
|
||||
if (depth) {
|
||||
shouldBeNonNull("gl = getWebGL(1, 1, { stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||
shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16");
|
||||
} else {
|
||||
shouldBeNonNull("gl = getWebGL(1, 1, { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||
shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0");
|
||||
}
|
||||
shouldBeTrue("gl.getParameter(gl.RED_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.GREEN_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.BLUE_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8");
|
||||
|
||||
shouldBeNonNull("contextAttribs = gl.getContextAttributes()");
|
||||
|
||||
gl.depthFunc(gl.NEVER);
|
||||
|
||||
var vertices = new Float32Array([
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, -1.0, 0.0]);
|
||||
var colors = new Uint8Array([
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255]);
|
||||
|
||||
drawAndReadPixel(gl, vertices, colors, 0, 0);
|
||||
correctColor = (contextAttribs.depth ? [0, 0, 0, 255] : [255, 0, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, correctColor);
|
||||
|
||||
if (fbHasDepth) {
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
drawAndReadPixel(gl, vertices, colors, 0, 0);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255]);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
}
|
||||
|
||||
function testStencilAndDepth(stencil, depth)
|
||||
{
|
||||
debug("Testing stencil = " + stencil + ", depth = " + depth);
|
||||
var creationString =
|
||||
"gl = getWebGL(1, 1, { depth: " + depth + ", stencil: " + stencil + ", antialias: false }, [ 0, 0, 0, 1 ], 1, 0)";
|
||||
shouldBeNonNull(creationString);
|
||||
|
||||
shouldBeTrue("gl.getParameter(gl.RED_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.GREEN_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.BLUE_BITS) >= 8");
|
||||
shouldBeTrue("gl.getParameter(gl.ALPHA_BITS) >= 8");
|
||||
if (depth)
|
||||
shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) >= 16");
|
||||
else
|
||||
shouldBeTrue("gl.getParameter(gl.DEPTH_BITS) == 0");
|
||||
|
||||
if (stencil)
|
||||
shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) >= 8");
|
||||
else
|
||||
shouldBeTrue("gl.getParameter(gl.STENCIL_BITS) == 0");
|
||||
|
||||
shouldBeNonNull("contextAttribs = gl.getContextAttributes()");
|
||||
if (!depth && contextAttribs.depth) {
|
||||
testFailed("WebGL implementation provided a depth buffer when it should not have");
|
||||
}
|
||||
if (!contextAttribs.depth)
|
||||
depth = false;
|
||||
if (!stencil && contextAttribs.stencil) {
|
||||
testFailed("WebGL implementation provided a stencil buffer when it should not have");
|
||||
}
|
||||
if (!contextAttribs.stencil)
|
||||
stencil = false;
|
||||
|
||||
gl.depthFunc(gl.ALWAYS);
|
||||
|
||||
gl.stencilFunc(gl.NEVER, 1, 1);
|
||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
||||
|
||||
var vertices = new Float32Array([
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, -1.0, 0.0]);
|
||||
var colors = new Uint8Array([
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255]);
|
||||
|
||||
drawAndReadPixel(gl, vertices, colors, 0, 0);
|
||||
correctColor = (stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, correctColor)
|
||||
|
||||
if (fbHasStencil) {
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
drawAndReadPixel(gl, vertices, colors, 0, 0);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255]);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
}
|
||||
|
||||
function testAntialias(antialias)
|
||||
{
|
||||
debug("Testing antialias = " + antialias);
|
||||
// Both the width and height of canvas are N.
|
||||
// Note that "N = 2" doesn't work for some post processing AA per the discussion at https://github.com/KhronosGroup/WebGL/pull/1977.
|
||||
var N = 3;
|
||||
if (antialias)
|
||||
shouldBeNonNull("gl = getWebGL(" + N + ", " + N + ", { depth: false, stencil: false, alpha: false, antialias: true }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||
else
|
||||
shouldBeNonNull("gl = getWebGL(" + N + ", " + N + ", { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||
shouldBeNonNull("contextAttribs = gl.getContextAttributes()");
|
||||
|
||||
var vertices = new Float32Array([
|
||||
1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0]);
|
||||
var colors = new Uint8Array([
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255]);
|
||||
drawAndReadPixel(gl, vertices, colors, 0, 0);
|
||||
var buf = new Uint8Array(N * N * 4);
|
||||
gl.readPixels(0, 0, N, N, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
redChannels[0] = buf[4 * (N + 1)]; // (1, 1)
|
||||
redChannels[1] = buf[4 * N * (N - 1)]; // left top
|
||||
redChannels[2] = buf[4 * (N - 1)]; // right bottom
|
||||
shouldBeTrue("redChannels[1] == 255 && redChannels[2] == 0");
|
||||
shouldBe("redChannels[0] != 255 && redChannels[0] != 0", "contextAttribs.antialias");
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
testDefault();
|
||||
testAlpha(true);
|
||||
testAlpha(false);
|
||||
testDepth(true);
|
||||
testDepth(false);
|
||||
testStencilAndDepth(true, false);
|
||||
testStencilAndDepth(false, false);
|
||||
testStencilAndDepth(true, true);
|
||||
testStencilAndDepth(false, true);
|
||||
testAntialias(true);
|
||||
testAntialias(false);
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test that contexts are freed and garbage collected reasonably</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
<script src="../../js/tests/iterable-test.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var test = IterableTest.createContextCreationAndDestructionTest();
|
||||
var iterations = parseInt(wtu.getUrlOptions().iterations, 10) || 50;
|
||||
IterableTest.run(test, iterations);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test that you can create large numbers of WebGL contexts.</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
<script src="../../js/tests/iterable-test.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var test = IterableTest.createContextCreationTest();
|
||||
var iterations = parseInt(wtu.getUrlOptions().iterations, 10) || 50;
|
||||
IterableTest.run(test, iterations);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test that context eviction and garbage collection do not interfere with each other</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
// See http://crbug.com/374086 for original failing case.
|
||||
description("Test that context eviction and garbage collection do not interfere with each other.");
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var total_iteration = 50;
|
||||
var array_count = 10;
|
||||
|
||||
var bank = [];
|
||||
for (var i = 0; i < array_count; i++)
|
||||
bank[i] = [];
|
||||
|
||||
for (var iter = 0; iter < total_iteration; ++iter) {
|
||||
for (var i = 0; i < array_count; i++)
|
||||
bank[i][iter * i] = iter;
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
canvas.width = 50;
|
||||
canvas.height = 50;
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
shouldBeTrue("program != null");
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
var pixel = new Uint8Array([0, 255, 0, 255]);
|
||||
gl.texImage2D(
|
||||
gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from iteration " + iter);
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script id='vs' type='x-shader/x-vertex'>
|
||||
attribute vec2 aPosCoord;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = vec4(aPosCoord, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id='fs' type='x-shader/x-fragment'>
|
||||
precision mediump float;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
var posCoords_arr = new Float32Array(2 * 4);
|
||||
var posCoords_buff = null;
|
||||
function DrawQuad(gl, prog, x0, y0, x1, y1) {
|
||||
gl.useProgram(prog);
|
||||
|
||||
if (!posCoords_buff) {
|
||||
posCoords_buff = gl.createBuffer();
|
||||
}
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, posCoords_buff);
|
||||
posCoords_arr[0] = x0;
|
||||
posCoords_arr[1] = y0;
|
||||
|
||||
posCoords_arr[2] = x1;
|
||||
posCoords_arr[3] = y0;
|
||||
|
||||
posCoords_arr[4] = x0;
|
||||
posCoords_arr[5] = y1;
|
||||
|
||||
posCoords_arr[6] = x1;
|
||||
posCoords_arr[7] = y1;
|
||||
gl.bufferData(gl.ARRAY_BUFFER, posCoords_arr, gl.STREAM_DRAW);
|
||||
|
||||
gl.enableVertexAttribArray(prog.aPosCoord);
|
||||
gl.vertexAttribPointer(prog.aPosCoord, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
function DrawSquare(gl, prog, size) {
|
||||
DrawQuad(gl, prog, -size, -size, size, size);
|
||||
}
|
||||
|
||||
function Reset(gl) {
|
||||
gl.canvas.width += 1;
|
||||
gl.canvas.width -= 1;
|
||||
}
|
||||
|
||||
var iColor;
|
||||
var pixel;
|
||||
var dataURL_pre;
|
||||
var dataURL_post;
|
||||
|
||||
function Test(gl, prog, shouldFinish) {
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.ZERO, gl.DST_ALPHA);
|
||||
|
||||
iColor = 64;
|
||||
var fColor = iColor / 255.0;
|
||||
|
||||
//////////////////
|
||||
|
||||
debug('clear(R,G,B,0)');
|
||||
|
||||
Reset(gl);
|
||||
|
||||
gl.clearColor(fColor, fColor, fColor, 0.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
dataURL_pre = gl.canvas.toDataURL();
|
||||
//console.log('Before blending: ' + dataURL_pre);
|
||||
|
||||
DrawSquare(gl, prog, 0.7);
|
||||
|
||||
WebGLTestUtils.checkCanvasRect(gl, gl.drawingBufferWidth/2,
|
||||
gl.drawingBufferHeight/2, 1, 1,
|
||||
[iColor, iColor, iColor, 255],
|
||||
'Should blend as if alpha is 1.0.');
|
||||
|
||||
dataURL_post = gl.canvas.toDataURL();
|
||||
//console.log('After blending: ' + dataURL_post);
|
||||
shouldBe("dataURL_post", "dataURL_pre");
|
||||
|
||||
//////////////////
|
||||
|
||||
debug('mask(R,G,B,0), clear(R,G,B,1)');
|
||||
|
||||
Reset(gl);
|
||||
|
||||
gl.colorMask(true, true, true, false);
|
||||
gl.clearColor(fColor, fColor, fColor, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.colorMask(true, true, true, true);
|
||||
|
||||
dataURL_pre = gl.canvas.toDataURL();
|
||||
//console.log('Before blending: ' + dataURL_pre);
|
||||
|
||||
DrawSquare(gl, prog, 0.7);
|
||||
|
||||
WebGLTestUtils.checkCanvasRect(gl, gl.drawingBufferWidth/2,
|
||||
gl.drawingBufferHeight/2, 1, 1,
|
||||
[iColor, iColor, iColor, 255],
|
||||
'Should blend as if alpha is 1.0.');
|
||||
|
||||
dataURL_post = gl.canvas.toDataURL();
|
||||
//console.log('After blending: ' + dataURL_post);
|
||||
shouldBe("dataURL_post", "dataURL_pre");
|
||||
|
||||
////////////////
|
||||
|
||||
WebGLTestUtils.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
|
||||
|
||||
if (shouldFinish)
|
||||
finishTest();
|
||||
}
|
||||
|
||||
var gl;
|
||||
function init() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
var attribs = {
|
||||
alpha: false,
|
||||
antialias: false,
|
||||
premultipliedAlpha: false,
|
||||
};
|
||||
gl = canvas.getContext('experimental-webgl', attribs);
|
||||
shouldBeNonNull(gl);
|
||||
shouldBe("gl.getParameter(gl.ALPHA_BITS)", "0");
|
||||
|
||||
var prog = WebGLTestUtils.setupProgram(gl, ['vs', 'fs']);
|
||||
shouldBeNonNull(prog);
|
||||
prog.aPosCoord = gl.getAttribLocation(prog, 'aPosCoord');
|
||||
|
||||
Test(gl, prog, false);
|
||||
|
||||
requestAnimationFrame(function(){ Test(gl, prog, true); });
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<canvas id='canvas'></canvas>
|
||||
<br/>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,308 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas;
|
||||
var gl;
|
||||
var shouldGenerateGLError;
|
||||
var WEBGL_lose_context;
|
||||
var new_WEBGL_lose_context;
|
||||
var bufferObjects;
|
||||
var program;
|
||||
var texture;
|
||||
var texColor = [255, 10, 20, 255];
|
||||
var allowRestore;
|
||||
var contextLostEventFired;
|
||||
var contextRestoredEventFired;
|
||||
var OES_vertex_array_object;
|
||||
var old_OES_vertex_array_object;
|
||||
var vertexArrayObject;
|
||||
var OES_texture_float;
|
||||
var newExtension;
|
||||
|
||||
function init()
|
||||
{
|
||||
enableJSTestPreVerboseLogging();
|
||||
description("Tests behavior under a restored context.");
|
||||
|
||||
shouldGenerateGLError = wtu.shouldGenerateGLError;
|
||||
testLosingContext();
|
||||
}
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.width = 1;
|
||||
canvas.height = 1;
|
||||
gl = wtu.create3DContext(canvas);
|
||||
WEBGL_lose_context = getExtensionAndAddProperty(gl, "WEBGL_lose_context");
|
||||
if (!WEBGL_lose_context) {
|
||||
debug("Could not find WEBGL_lose_context extension");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to get a few extensions
|
||||
OES_vertex_array_object = getExtensionAndAddProperty(gl, "OES_vertex_array_object");
|
||||
OES_texture_float = getExtensionAndAddProperty(gl, "OES_texture_float");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getExtensionAndAddProperty(gl, name) {
|
||||
var ext = wtu.getExtensionWithKnownPrefixes(gl, name);
|
||||
if (ext) {
|
||||
ext.webglTestProperty = true;
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
function reGetExtensionAndTestForProperty(gl, name, expectProperty) {
|
||||
newExtension = wtu.getExtensionWithKnownPrefixes(gl, name);
|
||||
// NOTE: while getting a extension after context lost/restored is allowed to fail
|
||||
// for the purpose the conformance tests it is not.
|
||||
//
|
||||
// Hypothetically the user can switch GPUs live. For example on Windows, install 2 GPUs,
|
||||
// then in the control panen enable 1, disable the others and visa versa. Since the GPUs
|
||||
// have different capabilities one or the other may not support a particlar extension.
|
||||
//
|
||||
// But, for the purpose of the conformance tests the context is expected to restore
|
||||
// on the same GPU and therefore the extensions that succeeded previously should
|
||||
// succeed on restore.
|
||||
shouldBeTrue("newExtension != null");
|
||||
if (expectProperty) {
|
||||
shouldBeTrue("newExtension.webglTestProperty === true");
|
||||
} else {
|
||||
shouldBeTrue("newExtension.webglTestProperty === undefined");
|
||||
}
|
||||
return newExtension;
|
||||
}
|
||||
|
||||
function testLosingContext()
|
||||
{
|
||||
if (!setupTest()) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Test losing a context and inability to restore it.");
|
||||
|
||||
canvas.addEventListener("webglcontextlost", function(e) {
|
||||
testLostContext(e);
|
||||
// restore the context after this event has exited.
|
||||
setTimeout(function() {
|
||||
// we didn't call prevent default so we should not be able to restore the context
|
||||
shouldGenerateGLError(gl, gl.INVALID_OPERATION, "WEBGL_lose_context.restoreContext()");
|
||||
testLosingAndRestoringContext();
|
||||
}, 0);
|
||||
});
|
||||
canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
|
||||
allowRestore = false;
|
||||
contextLostEventFired = false;
|
||||
contextRestoredEventFired = false;
|
||||
|
||||
testOriginalContext();
|
||||
WEBGL_lose_context.loseContext();
|
||||
// The context should be lost immediately.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
// gl methods should be no-ops
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
|
||||
// but the event should not have been fired.
|
||||
shouldBeFalse("contextLostEventFired");
|
||||
}
|
||||
|
||||
function testLosingAndRestoringContext()
|
||||
{
|
||||
if (!setupTest())
|
||||
finishTest();
|
||||
|
||||
debug("");
|
||||
debug("Test losing and restoring a context.");
|
||||
|
||||
canvas.addEventListener("webglcontextlost", function(e) {
|
||||
testLostContext(e);
|
||||
// restore the context after this event has exited.
|
||||
setTimeout(function() {
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
|
||||
// The context should still be lost. It will not get restored until the
|
||||
// webglrestorecontext event is fired.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
// gl methods should still be no-ops
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
|
||||
}, 0);
|
||||
});
|
||||
canvas.addEventListener("webglcontextrestored", function() {
|
||||
testRestoredContext();
|
||||
finishTest();
|
||||
});
|
||||
allowRestore = true;
|
||||
contextLostEventFired = false;
|
||||
contextRestoredEventFired = false;
|
||||
|
||||
testOriginalContext();
|
||||
WEBGL_lose_context.loseContext();
|
||||
// The context should be lost immediately.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
// gl methods should be no-ops
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP)");
|
||||
// but the event should not have been fired.
|
||||
shouldBeFalse("contextLostEventFired");
|
||||
}
|
||||
|
||||
function testRendering()
|
||||
{
|
||||
gl.clearColor(0, 0, 0, 255);
|
||||
gl.colorMask(1, 1, 1, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
program = wtu.setupSimpleTextureProgram(gl);
|
||||
bufferObjects = wtu.setupUnitQuad(gl);
|
||||
texture = wtu.createColoredTexture(gl, canvas.width, canvas.height, texColor);
|
||||
|
||||
gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
|
||||
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
|
||||
|
||||
var compare = texColor.slice(0, 3);
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, compare, "shouldBe " + compare);
|
||||
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
}
|
||||
|
||||
function testOriginalContext()
|
||||
{
|
||||
debug("Test valid context");
|
||||
shouldBeFalse("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
testRendering();
|
||||
debug("");
|
||||
}
|
||||
|
||||
function testLostContext(e)
|
||||
{
|
||||
debug("Test lost context");
|
||||
shouldBeFalse("contextLostEventFired");
|
||||
contextLostEventFired = true;
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
debug("");
|
||||
if (allowRestore)
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function testShouldNotRestoreContext(e)
|
||||
{
|
||||
testFailed("Should not restore the context unless preventDefault is called on the context lost event");
|
||||
debug("");
|
||||
}
|
||||
|
||||
function testResources(expected)
|
||||
{
|
||||
var tests = [
|
||||
"gl.bindTexture(gl.TEXTURE_2D, texture)",
|
||||
"gl.useProgram(program)",
|
||||
"gl.bindBuffer(gl.ARRAY_BUFFER, bufferObjects[0])",
|
||||
];
|
||||
|
||||
for (var i = 0; i < tests.length; ++i)
|
||||
shouldGenerateGLError(gl, expected, tests[i]);
|
||||
}
|
||||
|
||||
function testOESTextureFloat() {
|
||||
if (OES_texture_float) {
|
||||
// Extension must still be lost.
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
|
||||
// Try re-enabling extension
|
||||
OES_texture_float = reGetExtensionAndTestForProperty(gl, "OES_texture_float", false);
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null)");
|
||||
}
|
||||
}
|
||||
|
||||
function testOESVertexArrayObject() {
|
||||
if (OES_vertex_array_object) {
|
||||
// Extension must still be lost.
|
||||
shouldBeNull("OES_vertex_array_object.createVertexArrayOES()");
|
||||
// Try re-enabling extension
|
||||
|
||||
old_OES_vertex_array_object = OES_vertex_array_object;
|
||||
OES_vertex_array_object = reGetExtensionAndTestForProperty(gl, "OES_vertex_array_object", false);
|
||||
shouldBeTrue("OES_vertex_array_object.createVertexArrayOES() != null");
|
||||
shouldBeTrue("old_OES_vertex_array_object.createVertexArrayOES() == null");
|
||||
}
|
||||
}
|
||||
|
||||
function testExtensions() {
|
||||
testOESTextureFloat();
|
||||
testOESVertexArrayObject();
|
||||
// Only the WEBGL_lose_context extension should be the same object after context lost.
|
||||
new_WEBGL_lose_context = reGetExtensionAndTestForProperty(gl, "WEBGL_lose_context", true);
|
||||
}
|
||||
|
||||
function testRestoredContext()
|
||||
{
|
||||
debug("Test restored context");
|
||||
shouldBeFalse("contextRestoredEventFired");
|
||||
contextRestoredEventFired = true;
|
||||
shouldBeFalse("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
|
||||
// Validate that using old resources fails.
|
||||
testResources(gl.INVALID_OPERATION);
|
||||
|
||||
testRendering();
|
||||
|
||||
// Validate new resources created in testRendering().
|
||||
testResources(gl.NO_ERROR);
|
||||
|
||||
testExtensions();
|
||||
|
||||
debug("");
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,376 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu;
|
||||
var canvas;
|
||||
var gl;
|
||||
var shouldGenerateGLError;
|
||||
var extensionName;
|
||||
var extension;
|
||||
|
||||
var buffer;
|
||||
var framebuffer;
|
||||
var program;
|
||||
var renderbuffer;
|
||||
var shader;
|
||||
var texture;
|
||||
var uniformLocation;
|
||||
var arrayBuffer;
|
||||
var arrayBufferView
|
||||
var image;
|
||||
var video;
|
||||
var canvas2d;
|
||||
var ctx2d;
|
||||
var imageData;
|
||||
var float32array;
|
||||
var int32array;
|
||||
var OES_vertex_array_object;
|
||||
var vertexArrayObject;
|
||||
|
||||
function init()
|
||||
{
|
||||
wtu = WebGLTestUtils;
|
||||
canvas = document.getElementById("canvas");
|
||||
gl = wtu.create3DContext(canvas);
|
||||
shouldGenerateGLError = wtu.shouldGenerateGLError;
|
||||
|
||||
description("Tests behavior under a lost context");
|
||||
|
||||
// call testValidContext() before checking for the extension, because this is where we check
|
||||
// for the isContextLost() method, which we want to do regardless of the extension's presence.
|
||||
testValidContext();
|
||||
|
||||
extensionName = wtu.getSupportedExtensionWithKnownPrefixes(gl, "WEBGL_lose_context");
|
||||
if (!extensionName) {
|
||||
debug("Could not find WEBGL_lose_context extension");
|
||||
finishTest();
|
||||
return false;
|
||||
}
|
||||
extension = gl.getExtension(extensionName);
|
||||
|
||||
// need an extension that exposes new API methods.
|
||||
OES_vertex_array_object = wtu.getExtensionWithKnownPrefixes(gl, "OES_vertex_array_object");
|
||||
|
||||
canvas.addEventListener("webglcontextlost", testLostContext, false);
|
||||
|
||||
// We need to initialize |uniformLocation| before losing context.
|
||||
// Otherwise gl.getUniform() when context is lost will throw.
|
||||
uniformLocation = gl.getUniformLocation(program, "tex");
|
||||
loseContext();
|
||||
}
|
||||
|
||||
function loseContext()
|
||||
{
|
||||
debug("");
|
||||
debug("Lose context");
|
||||
|
||||
// Note: this will cause the context to be lost, but the
|
||||
// webglcontextlost event listener to be queued.
|
||||
extension.loseContext();
|
||||
debug("");
|
||||
}
|
||||
|
||||
function testValidContext()
|
||||
{
|
||||
debug("Test valid context");
|
||||
|
||||
shouldBeFalse("gl.isContextLost()");
|
||||
|
||||
arrayBuffer = new ArrayBuffer(4);
|
||||
arrayBufferView = new Int8Array(arrayBuffer);
|
||||
|
||||
// Generate resources for testing.
|
||||
buffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
program = wtu.setupSimpleTextureProgram(gl);
|
||||
renderbuffer = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
|
||||
shader = gl.createShader(gl.VERTEX_SHADER);
|
||||
texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
|
||||
// Test is queries that will later be false
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enable(gl.BLEND)");
|
||||
shouldBeTrue("gl.isBuffer(buffer)");
|
||||
shouldBeTrue("gl.isEnabled(gl.BLEND)");
|
||||
shouldBeTrue("gl.isFramebuffer(framebuffer)");
|
||||
shouldBeTrue("gl.isProgram(program)");
|
||||
shouldBeTrue("gl.isRenderbuffer(renderbuffer)");
|
||||
shouldBeTrue("gl.isShader(shader)");
|
||||
shouldBeTrue("gl.isTexture(texture)");
|
||||
|
||||
if (OES_vertex_array_object) {
|
||||
vertexArrayObject = OES_vertex_array_object.createVertexArrayOES();
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
shouldBeTrue("OES_vertex_array_object.isVertexArrayOES(vertexArrayObject)");
|
||||
}
|
||||
}
|
||||
|
||||
function testGLNOErrorFunctions(tests) {
|
||||
tests.forEach(function(test) {
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, test);
|
||||
});
|
||||
}
|
||||
|
||||
function testFunctionsThatReturnNULL(tests) {
|
||||
tests.forEach(function(test) {
|
||||
shouldBeNull(test);
|
||||
});
|
||||
}
|
||||
|
||||
function testLostContext()
|
||||
{
|
||||
debug("Test lost context");
|
||||
|
||||
// Functions with special return values.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
|
||||
shouldBe("gl.getAttribLocation(program, 'u_modelViewProjMatrix')", "-1");
|
||||
shouldBe("gl.getVertexAttribOffset(0, gl.VERTEX_ATTRIB_ARRAY_POINTER)", "0");
|
||||
|
||||
// Test the extension itself.
|
||||
shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.loseContext()");
|
||||
|
||||
image = document.createElement("img");
|
||||
video = document.createElement("video");
|
||||
canvas2d = document.createElement("canvas");
|
||||
ctx2d = canvas2d.getContext("2d");
|
||||
imageData = ctx2d.createImageData(1, 1);
|
||||
float32array = new Float32Array(1);
|
||||
int32array = new Int32Array(1);
|
||||
|
||||
// Functions returning void should return immediately.
|
||||
// This is untestable, but we can at least be sure they cause no errors
|
||||
// and the codepaths are exercised.
|
||||
var voidTests = [
|
||||
"gl.activeTexture(gl.TEXTURE0)",
|
||||
"gl.attachShader(program, shader)",
|
||||
"gl.bindBuffer(gl.ARRAY_BUFFER, buffer)",
|
||||
"gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)",
|
||||
"gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer)",
|
||||
"gl.bindTexture(gl.TEXTURE_2D, texture)",
|
||||
"gl.blendColor(1.0, 1.0, 1.0, 1.0)",
|
||||
"gl.blendEquation(gl.FUNC_ADD)",
|
||||
"gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD)",
|
||||
"gl.blendFunc(gl.ONE, gl.ONE)",
|
||||
"gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE)",
|
||||
"gl.bufferData(gl.ARRAY_BUFFER, 0, gl.STATIC_DRAW)",
|
||||
"gl.bufferData(gl.ARRAY_BUFFER, arrayBufferView, gl.STATIC_DRAW)",
|
||||
"gl.bufferData(gl.ARRAY_BUFFER, arrayBuffer, gl.STATIC_DRAW)",
|
||||
"gl.bufferSubData(gl.ARRAY_BUFFRE, 0, arrayBufferView)",
|
||||
"gl.bufferSubData(gl.ARRAY_BUFFRE, 0, arrayBuffer)",
|
||||
"gl.clear(gl.COLOR_BUFFER_BIT)",
|
||||
"gl.clearColor(1, 1, 1, 1)",
|
||||
"gl.clearDepth(1)",
|
||||
"gl.clearStencil(0)",
|
||||
"gl.colorMask(1, 1, 1, 1)",
|
||||
"gl.compileShader(shader)",
|
||||
"gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, 0, 0)",
|
||||
"gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 0, 0)",
|
||||
"gl.cullFace(gl.FRONT)",
|
||||
"gl.deleteBuffer(buffer)",
|
||||
"gl.deleteFramebuffer(framebuffer)",
|
||||
"gl.deleteProgram(program)",
|
||||
"gl.deleteRenderbuffer(renderbuffer)",
|
||||
"gl.deleteShader(shader)",
|
||||
"gl.deleteTexture(texture)",
|
||||
"gl.depthFunc(gl.NEVER)",
|
||||
"gl.depthMask(0)",
|
||||
"gl.depthRange(0, 1)",
|
||||
"gl.detachShader(program, shader)",
|
||||
"gl.disable(gl.BLEND)",
|
||||
"gl.disableVertexAttribArray(0)",
|
||||
"gl.drawArrays(gl.POINTS, 0, 0)",
|
||||
"gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_SHORT, 0)",
|
||||
"gl.enable(gl.BLEND)",
|
||||
"gl.enableVertexAttribArray(0)",
|
||||
"gl.finish()",
|
||||
"gl.flush()",
|
||||
"gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer)",
|
||||
"gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)",
|
||||
"gl.frontFace(gl.CW)",
|
||||
"gl.generateMipmap(gl.TEXTURE_2D)",
|
||||
"gl.hint(gl.GENERATE_MIPMAP_HINT, gl.FASTEST)",
|
||||
"gl.lineWidth(0)",
|
||||
"gl.linkProgram(program)",
|
||||
"gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0)",
|
||||
"gl.polygonOffset(0, 0)",
|
||||
"gl.readPixels(0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)",
|
||||
"gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0)",
|
||||
"gl.sampleCoverage(0, 0)",
|
||||
"gl.scissor(0, 0, 0, 0)",
|
||||
"gl.shaderSource(shader, '')",
|
||||
"gl.stencilFunc(gl.NEVER, 0, 0)",
|
||||
"gl.stencilFuncSeparate(gl.FRONT, gl.NEVER, 0, 0)",
|
||||
"gl.stencilMask(0)",
|
||||
"gl.stencilMaskSeparate(gl.FRONT, 0)",
|
||||
"gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP)",
|
||||
"gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.KEEP)",
|
||||
"gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)",
|
||||
"gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageData)",
|
||||
"gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)",
|
||||
"gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d)",
|
||||
"gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video)",
|
||||
"gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)",
|
||||
"gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)",
|
||||
"gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBufferView)",
|
||||
"gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData)",
|
||||
"gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image)",
|
||||
"gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d)",
|
||||
"gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video)",
|
||||
"gl.uniform1f(uniformLocation, 0)",
|
||||
"gl.uniform1fv(uniformLocation, float32array)",
|
||||
"gl.uniform1fv(uniformLocation, [0])",
|
||||
"gl.uniform1i(uniformLocation, 0)",
|
||||
"gl.uniform1iv(uniformLocation, int32array)",
|
||||
"gl.uniform1iv(uniformLocation, [0])",
|
||||
"gl.uniform2f(uniformLocation, 0, 0)",
|
||||
"gl.uniform2fv(uniformLocation, float32array)",
|
||||
"gl.uniform2fv(uniformLocation, [0, 0])",
|
||||
"gl.uniform2i(uniformLocation, 0, 0)",
|
||||
"gl.uniform2iv(uniformLocation, int32array)",
|
||||
"gl.uniform2iv(uniformLocation, [0, 0])",
|
||||
"gl.uniform3f(uniformLocation, 0, 0, 0)",
|
||||
"gl.uniform3fv(uniformLocation, float32array)",
|
||||
"gl.uniform3fv(uniformLocation, [0, 0, 0])",
|
||||
"gl.uniform3i(uniformLocation, 0, 0, 0)",
|
||||
"gl.uniform3iv(uniformLocation, int32array)",
|
||||
"gl.uniform3iv(uniformLocation, [0, 0, 0])",
|
||||
"gl.uniform4f(uniformLocation, 0, 0, 0, 0)",
|
||||
"gl.uniform4fv(uniformLocation, float32array)",
|
||||
"gl.uniform4fv(uniformLocation, [0, 0, 0, 0])",
|
||||
"gl.uniform4i(uniformLocation, 0, 0, 0, 0)",
|
||||
"gl.uniform4iv(uniformLocation, int32array)",
|
||||
"gl.uniform4iv(uniformLocation, [0, 0, 0, 0])",
|
||||
"gl.uniformMatrix2fv(uniformLocation, false, float32array)",
|
||||
"gl.uniformMatrix2fv(uniformLocation, false, [0, 0, 0, 0])",
|
||||
"gl.uniformMatrix3fv(uniformLocation, false, float32array)",
|
||||
"gl.uniformMatrix3fv(uniformLocation, false, [0, 0, 0, 0, 0, 0, 0, 0, 0])",
|
||||
"gl.uniformMatrix4fv(uniformLocation, false, float32array)",
|
||||
"gl.uniformMatrix4fv(uniformLocation, false, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])",
|
||||
"gl.useProgram(program)",
|
||||
"gl.validateProgram(program)",
|
||||
"gl.vertexAttrib1f(0, 0)",
|
||||
"gl.vertexAttrib1fv(0, float32array)",
|
||||
"gl.vertexAttrib1fv(0, [0])",
|
||||
"gl.vertexAttrib2f(0, 0, 0)",
|
||||
"gl.vertexAttrib2fv(0, float32array)",
|
||||
"gl.vertexAttrib2fv(0, [0, 0])",
|
||||
"gl.vertexAttrib3f(0, 0, 0, 0)",
|
||||
"gl.vertexAttrib3fv(0, float32array)",
|
||||
"gl.vertexAttrib3fv(0, [0, 0, 0])",
|
||||
"gl.vertexAttrib4f(0, 0, 0, 0, 0)",
|
||||
"gl.vertexAttrib4fv(0, float32array)",
|
||||
"gl.vertexAttrib4fv(0, [0, 0, 0, 0])",
|
||||
"gl.vertexAttribPointer(0, 0, gl.FLOAT, false, 0, 0)",
|
||||
"gl.viewport(0, 0, 0, 0)",
|
||||
];
|
||||
testGLNOErrorFunctions(voidTests);
|
||||
|
||||
// Functions return nullable values should all return null.
|
||||
var nullTests = [
|
||||
"gl.createBuffer()",
|
||||
"gl.createFramebuffer()",
|
||||
"gl.createProgram()",
|
||||
"gl.createRenderbuffer()",
|
||||
"gl.createShader(gl.GL_VERTEX_SHADER)",
|
||||
"gl.createTexture()",
|
||||
"gl.getActiveAttrib(program, 0)",
|
||||
"gl.getActiveUniform(program, 0)",
|
||||
"gl.getAttachedShaders(program)",
|
||||
"gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE)",
|
||||
"gl.getContextAttributes()",
|
||||
"gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)",
|
||||
"gl.getParameter(gl.CURRENT_PROGRAM)",
|
||||
"gl.getProgramInfoLog(program)",
|
||||
"gl.getProgramParameter(program, gl.LINK_STATUS)",
|
||||
"gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH)",
|
||||
"gl.getShaderInfoLog(shader)",
|
||||
"gl.getShaderParameter(shader, gl.SHADER_TYPE)",
|
||||
"gl.getShaderSource(shader)",
|
||||
"gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S)",
|
||||
"gl.getUniform(program, uniformLocation)",
|
||||
"gl.getUniformLocation(program, 'vPosition')",
|
||||
"gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)",
|
||||
"gl.getSupportedExtensions()",
|
||||
"gl.getExtension('" + extensionName + "')",
|
||||
];
|
||||
testFunctionsThatReturnNULL(nullTests);
|
||||
|
||||
// "Is" queries should all return false.
|
||||
shouldBeFalse("gl.isBuffer(buffer)");
|
||||
shouldBeFalse("gl.isEnabled(gl.BLEND)");
|
||||
shouldBeFalse("gl.isFramebuffer(framebuffer)");
|
||||
shouldBeFalse("gl.isProgram(program)");
|
||||
shouldBeFalse("gl.isRenderbuffer(renderbuffer)");
|
||||
shouldBeFalse("gl.isShader(shader)");
|
||||
shouldBeFalse("gl.isTexture(texture)");
|
||||
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
|
||||
// test extensions
|
||||
if (OES_vertex_array_object) {
|
||||
testGLNOErrorFunctions(
|
||||
[
|
||||
"OES_vertex_array_object.bindVertexArrayOES(vertexArrayObject)",
|
||||
"OES_vertex_array_object.isVertexArrayOES(vertexArrayObject)",
|
||||
"OES_vertex_array_object.deleteVertexArrayOES(vertexArrayObject)",
|
||||
]);
|
||||
testFunctionsThatReturnNULL(
|
||||
[
|
||||
"OES_vertex_array_object.createVertexArrayOES()",
|
||||
]);
|
||||
}
|
||||
|
||||
debug("");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,100 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
// This declaration needs to be global for "shouldBe" to see it
|
||||
var gl;
|
||||
|
||||
function init()
|
||||
{
|
||||
description('Verify that a WebGL context with alpha:false still works correctly after handling textures with an alpha channel.');
|
||||
|
||||
runTest();
|
||||
}
|
||||
|
||||
function getWebGL(contextAttribs)
|
||||
{
|
||||
return wtu.create3DContext("c", contextAttribs);
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
var buf = new Uint8Array(1 * 1 * 4);
|
||||
shouldBeNonNull("gl = getWebGL({ alpha: false, antialias: false })");
|
||||
|
||||
// Clear to black. Alpha channel of clearColor() is ignored.
|
||||
gl.clearColor(0.0, 0.0, 0.0, 0.7);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255],
|
||||
"Alpha channel of clearColor should be ignored");
|
||||
|
||||
wtu.waitForComposite(function() {
|
||||
// Make a new framebuffer and attach a texture with an alpha channel.
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
||||
|
||||
// Clear texture. Note that alpha channel is not 1.0.
|
||||
gl.clearColor(1.0, 0.0, 0.0, 0.5);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 0, 128],
|
||||
"Alpha channel of clearColor should be obeyed for FBO with alpha channel",
|
||||
1);
|
||||
|
||||
// Bind back buffer and check that its alpha channel is still 1.0.
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 255],
|
||||
"Alpha channel of back buffer should still be 255");
|
||||
finishTest();
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas width="20" height="20" style="border: 1px solid blue;" id="c"></canvas>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,95 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Context Release Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="host" style="width: 256px; height: 256px; border: 0;"></iframe>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test ensures that WebGL contexts are released properly upon page reload");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var host = document.getElementById("host");
|
||||
var testIterations = 25;
|
||||
var currentIteration = 0;
|
||||
|
||||
function refreshFrame() {
|
||||
if(currentIteration < testIterations) {
|
||||
currentIteration++;
|
||||
debug("");
|
||||
debug("Test " + currentIteration + " of " + testIterations);
|
||||
host.src = "resources/context-release-upon-reload-child.html";
|
||||
} else {
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
function testContext() {
|
||||
var gl = host.contentWindow.glContext;
|
||||
assertMsg(gl != null, "context was created properly");
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
|
||||
|
||||
if(gl.canvas.width != gl.drawingBufferWidth ||
|
||||
gl.canvas.height != gl.drawingBufferHeight) {
|
||||
testFailed("Buffer was the wrong size: " +
|
||||
gl.drawingBufferWidth + "x" + gl.drawingBufferHeight);
|
||||
} else {
|
||||
testPassed("Buffer was the correct size: " +
|
||||
gl.drawingBufferWidth + "x" + gl.drawingBufferHeight);
|
||||
refreshFrame();
|
||||
}
|
||||
|
||||
gl = null;
|
||||
}
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
if(event.data == "Ready") {
|
||||
testContext();
|
||||
}
|
||||
});
|
||||
|
||||
refreshFrame();
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,95 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Context Release Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="host" style="width: 256px; height: 256px; border: 0;"></iframe>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test ensures that WebGL contexts are released properly when a worker is used");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var host = document.getElementById("host");
|
||||
var testIterations = 25;
|
||||
var currentIteration = 0;
|
||||
|
||||
function refreshFrame() {
|
||||
if(currentIteration < testIterations) {
|
||||
currentIteration++;
|
||||
debug("");
|
||||
debug("Test " + currentIteration + " of " + testIterations);
|
||||
host.src = "resources/context-release-child-with-worker.html";
|
||||
} else {
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
function testContext() {
|
||||
var gl = host.contentWindow.glContext;
|
||||
assertMsg(gl != null, "context was created properly");
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
|
||||
|
||||
if(gl.canvas.width != gl.drawingBufferWidth ||
|
||||
gl.canvas.height != gl.drawingBufferHeight) {
|
||||
testFailed("Buffer was the wrong size: " +
|
||||
gl.drawingBufferWidth + "x" + gl.drawingBufferHeight);
|
||||
} else {
|
||||
testPassed("Buffer was the correct size: " +
|
||||
gl.drawingBufferWidth + "x" + gl.drawingBufferHeight);
|
||||
refreshFrame();
|
||||
}
|
||||
|
||||
gl = null;
|
||||
}
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
if(event.data == "Ready") {
|
||||
testContext();
|
||||
}
|
||||
});
|
||||
|
||||
refreshFrame();
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,115 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
// These declarations need to be global for "shouldBe" to see them
|
||||
var gl;
|
||||
var pixel = [0, 0, 0, 1];
|
||||
var canvas;
|
||||
|
||||
function init()
|
||||
{
|
||||
description('Verify that changing the size of an antialiased WebGL context does not cause it to stop working.');
|
||||
|
||||
runTest();
|
||||
}
|
||||
|
||||
function getWebGL(canvasWidth, canvasHeight, contextAttribs)
|
||||
{
|
||||
canvas = document.createElement("canvas");
|
||||
if (!canvas)
|
||||
return null;
|
||||
canvas.width = canvasWidth;
|
||||
canvas.height = canvasHeight;
|
||||
|
||||
gl = WebGLTestUtils.create3DContext(canvas, contextAttribs);
|
||||
if (!gl)
|
||||
return null;
|
||||
|
||||
return gl;
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
shouldBeNonNull("gl = getWebGL(1, 1, { alpha: false, antialias: true })");
|
||||
|
||||
// Clear to black.
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// Check that the pixel's R channel is 0.
|
||||
var buf = new Uint8Array(1 * 1 * 4);
|
||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
pixel[0] = buf[0];
|
||||
shouldBeTrue("pixel[0] == 0");
|
||||
|
||||
// Change the size of the canvas.
|
||||
canvas.width = 3;
|
||||
canvas.height = 3;
|
||||
|
||||
// Clear to black.
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// Clear the top-left pixel to white.
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
gl.scissor(0, 0, 1, 1);
|
||||
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// Check that the top-left pixel has R channel 255.
|
||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
pixel[0] = buf[0];
|
||||
shouldBeTrue("pixel[0] == 255");
|
||||
|
||||
// Check that the bottom-right pixel has R channel 0.
|
||||
gl.readPixels(2, 2, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
pixel[0] = buf[0];
|
||||
shouldBeTrue("pixel[0] == 0");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,76 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Canvas Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<canvas id="canvas2d" width="40" height="40"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test ensures WebGL implementations interact correctly with the canvas tag.");
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
assertMsg(window.WebGLRenderingContext,
|
||||
"WebGLRenderingContext should be a member of window");
|
||||
assertMsg('WebGLRenderingContext' in window,
|
||||
"WebGLRenderingContext should be 'in' window");
|
||||
assertMsg(Object.getPrototypeOf(WebGLRenderingContext.prototype) === Object.prototype,
|
||||
"WebGLRenderingContext should only have Object in it's prototype chain");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("Checking context type");
|
||||
assertMsg(gl instanceof WebGLRenderingContext,
|
||||
"context type should be WebGLRenderingContext");
|
||||
}
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,90 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Tests calling WebGL APIs with objects from other contexts");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var contextA = wtu.create3DContext();
|
||||
var contextB = wtu.create3DContext();
|
||||
var programA = wtu.loadStandardProgram(contextA);
|
||||
var programB = wtu.loadStandardProgram(contextB);
|
||||
var shaderA = wtu.loadStandardVertexShader(contextA);
|
||||
var shaderB = wtu.loadStandardVertexShader(contextB);
|
||||
var textureA = contextA.createTexture();
|
||||
var textureB = contextB.createTexture();
|
||||
var frameBufferA = contextA.createFramebuffer();
|
||||
var frameBufferB = contextB.createFramebuffer();
|
||||
var renderBufferA = contextA.createRenderbuffer();
|
||||
var renderBufferB = contextB.createRenderbuffer();
|
||||
var locationA = contextA.getUniformLocation(programA, 'u_modelViewProjMatrix');
|
||||
var locationB = contextB.getUniformLocation(programB, 'u_modelViewProjMatrix');
|
||||
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.compileShader(shaderB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.linkProgram(programB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programA, shaderB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programB, shaderA)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.attachShader(programB, shaderB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programA, shaderB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programB, shaderA)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.detachShader(programB, shaderB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.shaderSource(shaderB, 'foo')");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindAttribLocation(programB, 0, 'foo')");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindFramebuffer(contextA.FRAMEBUFFER, frameBufferB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindRenderbuffer(contextA.RENDERBUFFER, renderBufferB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.bindTexture(contextA.TEXTURE_2D, textureB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferRenderbuffer(contextA.FRAMEBUFFER, contextA.DEPTH_ATTACHMENT, contextA.RENDERBUFFER, renderBufferB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.framebufferTexture2D(contextA.FRAMEBUFFER, contextA.COLOR_ATTACHMENT0, contextA.TEXTURE_2D, textureB, 0)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getProgramParameter(programB, 0)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getProgramInfoLog(programB, 0)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderParameter(shaderB, 0)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderInfoLog(shaderB, 0)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getShaderSource(shaderB)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniform(programB, locationA)");
|
||||
wtu.shouldGenerateGLError(contextA, contextA.INVALID_OPERATION, "contextA.getUniformLocation(programB, 'u_modelViewProjMatrix')");
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,241 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Methods Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test ensures that the WebGL context has all the methods in the specification.");
|
||||
|
||||
var methods = [
|
||||
"getContextAttributes",
|
||||
"activeTexture",
|
||||
"attachShader",
|
||||
"bindAttribLocation",
|
||||
"bindBuffer",
|
||||
"bindFramebuffer",
|
||||
"bindRenderbuffer",
|
||||
"bindTexture",
|
||||
"blendColor",
|
||||
"blendEquation",
|
||||
"blendEquationSeparate",
|
||||
"blendFunc",
|
||||
"blendFuncSeparate",
|
||||
"bufferData",
|
||||
"bufferSubData",
|
||||
"checkFramebufferStatus",
|
||||
"clear",
|
||||
"clearColor",
|
||||
"clearDepth",
|
||||
"clearStencil",
|
||||
"colorMask",
|
||||
"compileShader",
|
||||
"compressedTexImage2D",
|
||||
"compressedTexSubImage2D",
|
||||
"copyTexImage2D",
|
||||
"copyTexSubImage2D",
|
||||
"createBuffer",
|
||||
"createFramebuffer",
|
||||
"createProgram",
|
||||
"createRenderbuffer",
|
||||
"createShader",
|
||||
"createTexture",
|
||||
"cullFace",
|
||||
"deleteBuffer",
|
||||
"deleteFramebuffer",
|
||||
"deleteProgram",
|
||||
"deleteRenderbuffer",
|
||||
"deleteShader",
|
||||
"deleteTexture",
|
||||
"depthFunc",
|
||||
"depthMask",
|
||||
"depthRange",
|
||||
"detachShader",
|
||||
"disable",
|
||||
"disableVertexAttribArray",
|
||||
"drawArrays",
|
||||
"drawElements",
|
||||
"enable",
|
||||
"enableVertexAttribArray",
|
||||
"finish",
|
||||
"flush",
|
||||
"framebufferRenderbuffer",
|
||||
"framebufferTexture2D",
|
||||
"frontFace",
|
||||
"generateMipmap",
|
||||
"getActiveAttrib",
|
||||
"getActiveUniform",
|
||||
"getAttachedShaders",
|
||||
"getAttribLocation",
|
||||
"getParameter",
|
||||
"getBufferParameter",
|
||||
"getError",
|
||||
"getExtension",
|
||||
"getFramebufferAttachmentParameter",
|
||||
"getProgramParameter",
|
||||
"getProgramInfoLog",
|
||||
"getRenderbufferParameter",
|
||||
"getShaderParameter",
|
||||
"getShaderInfoLog",
|
||||
"getShaderPrecisionFormat",
|
||||
"getShaderSource",
|
||||
"getSupportedExtensions",
|
||||
"getTexParameter",
|
||||
"getUniform",
|
||||
"getUniformLocation",
|
||||
"getVertexAttrib",
|
||||
"getVertexAttribOffset",
|
||||
"hint",
|
||||
"isBuffer",
|
||||
"isContextLost",
|
||||
"isEnabled",
|
||||
"isFramebuffer",
|
||||
"isProgram",
|
||||
"isRenderbuffer",
|
||||
"isShader",
|
||||
"isTexture",
|
||||
"lineWidth",
|
||||
"linkProgram",
|
||||
"pixelStorei",
|
||||
"polygonOffset",
|
||||
"readPixels",
|
||||
"renderbufferStorage",
|
||||
"sampleCoverage",
|
||||
"scissor",
|
||||
"shaderSource",
|
||||
"stencilFunc",
|
||||
"stencilFuncSeparate",
|
||||
"stencilMask",
|
||||
"stencilMaskSeparate",
|
||||
"stencilOp",
|
||||
"stencilOpSeparate",
|
||||
"texImage2D",
|
||||
"texParameterf",
|
||||
"texParameteri",
|
||||
"texSubImage2D",
|
||||
"uniform1f",
|
||||
"uniform1fv",
|
||||
"uniform1i",
|
||||
"uniform1iv",
|
||||
"uniform2f",
|
||||
"uniform2fv",
|
||||
"uniform2i",
|
||||
"uniform2iv",
|
||||
"uniform3f",
|
||||
"uniform3fv",
|
||||
"uniform3i",
|
||||
"uniform3iv",
|
||||
"uniform4f",
|
||||
"uniform4fv",
|
||||
"uniform4i",
|
||||
"uniform4iv",
|
||||
"uniformMatrix2fv",
|
||||
"uniformMatrix3fv",
|
||||
"uniformMatrix4fv",
|
||||
"useProgram",
|
||||
"validateProgram",
|
||||
"vertexAttrib1f",
|
||||
"vertexAttrib1fv",
|
||||
"vertexAttrib2f",
|
||||
"vertexAttrib2fv",
|
||||
"vertexAttrib3f",
|
||||
"vertexAttrib3fv",
|
||||
"vertexAttrib4f",
|
||||
"vertexAttrib4fv",
|
||||
"vertexAttribPointer",
|
||||
"viewport"
|
||||
];
|
||||
|
||||
// Properties to be ignored because they were added in versions of the
|
||||
// spec that are backward-compatible with this version
|
||||
var ignoredMethods = [
|
||||
// There is no official spec for the commit API yet, the proposal link is:
|
||||
// https://wiki.whatwg.org/wiki/OffscreenCanvas
|
||||
"commit"
|
||||
];
|
||||
|
||||
function assertFunction(v, f) {
|
||||
try {
|
||||
if (typeof v[f] != "function") {
|
||||
testFailed("Property either does not exist or is not a function: " + f);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch(e) {
|
||||
testFailed("Trying to access the property '" + f + "' threw an error: "+e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var passed = true;
|
||||
for (var i=0; i<methods.length; i++) {
|
||||
var r = assertFunction(gl, methods[i]);
|
||||
passed = passed && r;
|
||||
}
|
||||
if (passed) {
|
||||
testPassed("All WebGL methods found.");
|
||||
}
|
||||
var extended = false;
|
||||
for (var i in gl) {
|
||||
if (typeof gl[i] == "function" && methods.indexOf(i) == -1 && ignoredMethods.indexOf(i) == -1) {
|
||||
if (!extended) {
|
||||
extended = true;
|
||||
testFailed("Also found the following extra methods:");
|
||||
}
|
||||
testFailed(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!extended) {
|
||||
testPassed("No extra methods found on WebGL context.");
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,268 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the WebGL premultipliedAlpha context creation flag.</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div><div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
// wtu.create3DContext(...) will set antialias to false by default
|
||||
// if the antialias property is not set to true explicitly.
|
||||
// To cover the antialias case, it needs to set antialias to true
|
||||
// explicitly.
|
||||
var tests = [
|
||||
// If premultipliedAlpha is true and antialias is false then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128
|
||||
{ creationAttributes: {},
|
||||
sentColor: [32, 64, 128, 128],
|
||||
expectedColor: [64, 128, 255, 128],
|
||||
errorRange: 2,
|
||||
imageFormat: "image/png"
|
||||
},
|
||||
// If premultipliedAlpha is true and antialias is true then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128
|
||||
{ creationAttributes: {antialias: true},
|
||||
sentColor: [32, 64, 128, 128],
|
||||
expectedColor: [64, 128, 255, 128],
|
||||
errorRange: 2,
|
||||
imageFormat: "image/png"
|
||||
},
|
||||
// If premultipliedAlpha is true and antialias is false then
|
||||
// [texture] [canvas] [texture]
|
||||
// 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128
|
||||
{ creationAttributes: {},
|
||||
sentColor: [32, 64, 128, 128],
|
||||
expectedColor: [64, 128, 255, 128],
|
||||
errorRange: 2,
|
||||
},
|
||||
// If premultipliedAlpha is true and antialias is true then
|
||||
// [texture] [canvas] [texture]
|
||||
// 32, 64, 128, 128 -> 64, 128, 255, 128 -> 64, 128, 255, 128
|
||||
{ creationAttributes: {antialias: true},
|
||||
sentColor: [32, 64, 128, 128],
|
||||
expectedColor: [64, 128, 255, 128],
|
||||
errorRange: 2,
|
||||
},
|
||||
// If premultipliedAlpha is false and antialias is false then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1
|
||||
{ creationAttributes: {premultipliedAlpha: false},
|
||||
sentColor: [255, 192, 128, 1],
|
||||
expectedColor: [255, 192, 128, 1],
|
||||
errorRange: 0,
|
||||
imageFormat: "image/png"
|
||||
},
|
||||
// If premultipliedAlpha is false and antialias is true then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1
|
||||
{ creationAttributes: {premultipliedAlpha: false, antialias: true},
|
||||
sentColor: [255, 192, 128, 1],
|
||||
expectedColor: [255, 192, 128, 1],
|
||||
errorRange: 0,
|
||||
imageFormat: "image/png"
|
||||
},
|
||||
// If premultipliedAlpha is false and antialias is false then
|
||||
// [texture] [canvas] [texture]
|
||||
// 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1
|
||||
{ creationAttributes: {premultipliedAlpha: false},
|
||||
sentColor: [255, 192, 128, 1],
|
||||
expectedColor: [255, 192, 128, 1],
|
||||
errorRange: 0,
|
||||
},
|
||||
// If premultipliedAlpha is false and antialias is true then
|
||||
// [texture] [canvas] [texture]
|
||||
// 255, 192, 128, 1 -> 255, 192, 128, 1 -> 255, 192, 128, 1
|
||||
{ creationAttributes: {premultipliedAlpha: false, antialias: true},
|
||||
sentColor: [255, 192, 128, 1],
|
||||
expectedColor: [255, 192, 128, 1],
|
||||
errorRange: 0,
|
||||
},
|
||||
// If premultipliedAlpha is false and antialias is false then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 255, 255, 255, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255
|
||||
{ creationAttributes: {premultipliedAlpha: false},
|
||||
sentColor: [255, 255, 255, 128],
|
||||
expectedColor: [128, 128, 128, 255],
|
||||
errorRange: 2,
|
||||
imageFormat: "image/jpeg"
|
||||
},
|
||||
// If premultipliedAlpha is false and antialias is true then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 255, 255, 255, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255
|
||||
{ creationAttributes: {premultipliedAlpha: false, antialias: true},
|
||||
sentColor: [255, 255, 255, 128],
|
||||
expectedColor: [128, 128, 128, 255],
|
||||
errorRange: 2,
|
||||
imageFormat: "image/jpeg"
|
||||
},
|
||||
// If premultipliedAlpha is true and antialias is false then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 128, 128, 128, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255
|
||||
{ creationAttributes: {},
|
||||
sentColor: [128, 128, 128, 128],
|
||||
expectedColor: [128, 128, 128, 255],
|
||||
errorRange: 2,
|
||||
imageFormat: "image/jpeg"
|
||||
},
|
||||
// If premultipliedAlpha is true and antialias is true then
|
||||
// [texture] [canvas] [dataURL]
|
||||
// 128, 128, 128, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255
|
||||
{ creationAttributes: {antialias: true},
|
||||
sentColor: [128, 128, 128, 128],
|
||||
expectedColor: [128, 128, 128, 255],
|
||||
errorRange: 2,
|
||||
imageFormat: "image/jpeg"
|
||||
}
|
||||
];
|
||||
|
||||
var g_count = 0;
|
||||
var gl;
|
||||
var canvas;
|
||||
var premultipliedAlpha;
|
||||
|
||||
enableJSTestPreVerboseLogging();
|
||||
description("Test the WebGL premultipliedAlpha context creation flag.");
|
||||
doNextTest();
|
||||
function doNextTest() {
|
||||
if (g_count < tests.length) {
|
||||
var test = tests[g_count++];
|
||||
canvas = document.createElement("canvas");
|
||||
// Need to preserve drawing buffer to load it in a callback
|
||||
test.creationAttributes.preserveDrawingBuffer = true;
|
||||
gl = wtu.create3DContext(canvas, test.creationAttributes);
|
||||
var premultipliedAlpha = test.creationAttributes.premultipliedAlpha != false;
|
||||
var antialias = test.creationAttributes.antialias == true;
|
||||
debug("")
|
||||
debug("testing: premultipliedAlpha: " + premultipliedAlpha
|
||||
+ ", antialias: " + antialias
|
||||
+ ", imageFormat: " + test.imageFormat);
|
||||
|
||||
shouldBe('gl.getContextAttributes().premultipliedAlpha', premultipliedAlpha.toString());
|
||||
shouldBeTrue('gl.getContextAttributes().preserveDrawingBuffer');
|
||||
|
||||
wtu.log(gl.getContextAttributes());
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
||||
var tex = gl.createTexture();
|
||||
wtu.fillTexture(gl, tex, 2, 2, test.sentColor, 0);
|
||||
var loc = gl.getUniformLocation(program, "tex");
|
||||
gl.uniform1i(loc, 0);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from drawing.");
|
||||
|
||||
var loadTexture = function() {
|
||||
debug("loadTexture called");
|
||||
var pngTex = gl.createTexture();
|
||||
// not needed as it's the default
|
||||
// gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
||||
wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);');
|
||||
gl.bindTexture(gl.TEXTURE_2D, pngTex);
|
||||
if (test.imageFormat) {
|
||||
// create texture from image
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this);
|
||||
} else {
|
||||
// create texture from canvas
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
|
||||
}
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from creating copy.");
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from 2nd drawing.");
|
||||
wtu.checkCanvas(
|
||||
gl, test.expectedColor,
|
||||
"should draw with " + test.expectedColor, test.errorRange);
|
||||
|
||||
doNextTest();
|
||||
}
|
||||
|
||||
var loadTextureError = function() {
|
||||
testFailed("Creating image from canvas failed. Image src: " + this.src);
|
||||
finishTest();
|
||||
}
|
||||
|
||||
var shrinkString = function(string) {
|
||||
if (string.length < 63) {
|
||||
return string;
|
||||
}
|
||||
return string.substr(0, 30) + "..." + string.substr(string.length - 30);
|
||||
}
|
||||
|
||||
if (test.imageFormat) {
|
||||
// Load canvas into string using toDataURL
|
||||
debug("Calling canvas.toDataURL('" + test.imageFormat + "')");
|
||||
var imageUrl = canvas.toDataURL(test.imageFormat);
|
||||
debug("imageUrl = '" + shrinkString(imageUrl) + "'");
|
||||
if (test.imageFormat != "image/png" &&
|
||||
(imageUrl.indexOf("data:image/png,") == 0 ||
|
||||
imageUrl.indexOf("data:image/png;") == 0)) {
|
||||
debug("Image format " + test.imageFormat + " not supported; skipping");
|
||||
setTimeout(doNextTest, 0);
|
||||
} else {
|
||||
// Load string into the texture
|
||||
debug("Waiting for image.onload");
|
||||
var input = wtu.makeImage(imageUrl, loadTexture, loadTextureError);
|
||||
}
|
||||
} else {
|
||||
// Load canvas into the texture asynchronously (to prevent unbounded stack consumption)
|
||||
debug("Waiting for setTimeout");
|
||||
setTimeout(loadTexture, 0);
|
||||
}
|
||||
} else {
|
||||
var successfullyParsed = true;
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Resource Sharing.</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example1" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
|
||||
<canvas id="example2" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("Tests that resources can not be shared.");
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl1 = wtu.create3DContext("example1");
|
||||
var gl2 = wtu.create3DContext("example2");
|
||||
assertMsg(gl1 && gl2,
|
||||
"Got 3d context.");
|
||||
|
||||
var vertexObject = gl1.createBuffer();
|
||||
gl2.bindBuffer(gl2.ARRAY_BUFFER, vertexObject);
|
||||
assertMsg(
|
||||
gl2.getError() == gl2.INVALID_OPERATION,
|
||||
"attempt to use a resource from the wrong context should fail with INVALID_OPERATION");
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html style="margin: 0; padding: 0;">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple WebGL context with Worker</title>
|
||||
<script src="../../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; overflow: hidden;">
|
||||
<canvas id="c" width="1680" height="1050" style="width: 256px; height: 256px;"> <!-- scaled to fit page better -->
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
var myWorker = new Worker("context-release-worker.js");
|
||||
|
||||
var gl = wtu.create3DContext("c", { antialias: false });
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
|
||||
if (parent) {
|
||||
window.glContext = gl;
|
||||
parent.postMessage("Ready", "*");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,75 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html style="margin: 0; padding: 0;">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Simple WebGL context</title>
|
||||
<script src="../../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; overflow: hidden;">
|
||||
<canvas id="c" width="1680" height="1050" style="width: 256px; height: 256px;"> <!-- scaled to fit page better -->
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var gl = wtu.create3DContext("c", { antialias: false });
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
||||
|
||||
if (parent) {
|
||||
window.glContext = gl;
|
||||
parent.postMessage("Ready", "*");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
// Simple worker used to provoke WebGL context release bugs on Chrome
|
||||
|
||||
postMessage("Hello World");
|
||||
close();
|
|
@ -0,0 +1,72 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL User-Defined Properties Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body onload="initialize()">
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test ensures that if user-defined properties are set on the WebGL context object, that they don't disappear after garbage collection.");
|
||||
|
||||
var gl2 = null;
|
||||
|
||||
function initialize() {
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl1 = wtu.create3DContext(canvas);
|
||||
if (!gl1) {
|
||||
testFailed("WebGL context does not exist");
|
||||
finishTest();
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
gl1.myProperty = 2;
|
||||
wtu.requestAnimFrame(runTest);
|
||||
}
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
webglHarnessCollectGarbage();
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
gl2 = wtu.create3DContext(canvas);
|
||||
shouldBe('gl2.myProperty', '2');
|
||||
finishTest();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,39 @@
|
|||
--min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays-out-of-bounds.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 ext-blend-minmax.html
|
||||
--min-version 1.0.4 ext-disjoint-timer-query.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 ext-frag-depth.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 ext-shader-texture-lod.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 ext-sRGB.html
|
||||
--min-version 1.0.2 ext-texture-filter-anisotropic.html
|
||||
--min-version 1.0.2 get-extension.html
|
||||
--max-version 1.9.9 oes-standard-derivatives.html
|
||||
--max-version 1.9.9 oes-texture-float-with-canvas.html
|
||||
--max-version 1.9.9 oes-texture-float-with-image-data.html
|
||||
--max-version 1.9.9 oes-texture-float-with-image.html
|
||||
--max-version 1.9.9 oes-texture-float-with-video.html
|
||||
--max-version 1.9.9 oes-texture-float.html
|
||||
--max-version 1.9.9 oes-vertex-array-object.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-vertex-array-object-bufferData.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float.html
|
||||
--min-version 1.0.3 oes-texture-float-linear.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float-linear.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float-with-canvas.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float-with-image-data.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float-with-image.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 oes-texture-half-float-with-video.html
|
||||
--min-version 1.0.2 --max-version 1.9.9 oes-element-index-uint.html
|
||||
webgl-debug-renderer-info.html
|
||||
webgl-debug-shaders.html
|
||||
//--min-version 1.0.3 webgl-compressed-texture-atc.html // Removed for WebGL 2.0.0
|
||||
--min-version 1.0.4 webgl-compressed-texture-etc.html
|
||||
--min-version 1.0.3 webgl-compressed-texture-pvrtc.html
|
||||
--min-version 1.0.2 webgl-compressed-texture-s3tc.html
|
||||
--min-version 1.0.4 webgl-compressed-texture-s3tc-srgb.html
|
||||
--min-version 1.0.3 webgl-compressed-texture-size-limit.html
|
||||
--min-version 1.0.2 --max-version 1.9.9 webgl-depth-texture.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 webgl-draw-buffers.html
|
||||
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-framebuffer-unsupported.html
|
||||
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-max-draw-buffers.html
|
||||
--min-version 1.0.3 webgl-shared-resources.html
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/out-of-bounds-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test of drawArraysInstancedANGLE and drawElementsInstancedANGLE with out-of-bounds parameters");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
var gl = wtu.create3DContext();
|
||||
var ext = wtu.getExtensionWithKnownPrefixes(gl, "ANGLE_instanced_arrays");
|
||||
if (!ext) {
|
||||
testPassed("No ANGLE_instanced_arrays support -- this is legal");
|
||||
} else {
|
||||
testPassed("Successfully enabled ANGLE_instanced_arrays extension");
|
||||
debug("");
|
||||
debug("Test with 1 instance without instanced attributes");
|
||||
debug("");
|
||||
OutOfBoundsTest.runDrawArraysTest("ext.drawArraysInstancedANGLE(gl.TRIANGLES, $(offset), $(count), 1)", gl, wtu, ext);
|
||||
debug("");
|
||||
OutOfBoundsTest.runDrawElementsTest("ext.drawElementsInstancedANGLE(gl.TRIANGLES, $(count), $(type), $(offset), 1)", gl, wtu, ext);
|
||||
debug("");
|
||||
debug("Test with 2 instances without instanced attributes");
|
||||
debug("");
|
||||
OutOfBoundsTest.runDrawArraysTest("ext.drawArraysInstancedANGLE(gl.TRIANGLES, $(offset), $(count), 2)", gl, wtu, ext);
|
||||
debug("");
|
||||
OutOfBoundsTest.runDrawElementsTest("ext.drawElementsInstancedANGLE(gl.TRIANGLES, $(count), $(type), $(offset), 2)", gl, wtu, ext);
|
||||
debug("");
|
||||
OutOfBoundsTest.runDrawArraysInstancedTest("ext.drawArraysInstancedANGLE(gl.TRIANGLES, $(offset), $(count), $(primcount))", gl, wtu, ext);
|
||||
debug("");
|
||||
OutOfBoundsTest.runDrawElementsInstancedTest("ext.drawElementsInstancedANGLE(gl.TRIANGLES, $(count), $(type), $(offset), $(primcount))", gl, wtu, ext);
|
||||
debug("");
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,654 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL ANGLE_instanced_arrays Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/desktop-gl-constants.js"></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<!-- Shaders for testing instanced draws -->
|
||||
<script id="outputVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 aPosition;
|
||||
attribute vec2 aOffset;
|
||||
attribute vec4 aColor;
|
||||
varying vec4 vColor;
|
||||
void main() {
|
||||
vColor = aColor;
|
||||
gl_Position = aPosition + vec4(aOffset, 0.0, 0.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="outputFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec4 vColor;
|
||||
void main() {
|
||||
gl_FragColor = vColor;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="drawArraysTestVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec3 aPosition;
|
||||
attribute vec3 aInstancePos;
|
||||
uniform vec3 uOffset;
|
||||
void main() {
|
||||
gl_Position = vec4(aPosition.xyz + aInstancePos.xyz + uOffset, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="drawArraysTestFragmentShader" type="x-shader/x-fragment">
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0, 0, 0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the ANGLE_instanced_arrays extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
var vaoext = null;
|
||||
|
||||
var positionLoc = 0;
|
||||
var offsetLoc = 2;
|
||||
var colorLoc = 3;
|
||||
var program;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
finishTest();
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
runDivisorTestDisabled();
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = wtu.getExtensionWithKnownPrefixes(gl, "ANGLE_instanced_arrays");
|
||||
if (!ext) {
|
||||
testPassed("No ANGLE_instanced_arrays support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
finishTest();
|
||||
} else {
|
||||
testPassed("Successfully enabled ANGLE_instanced_arrays extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
runDivisorTestEnabled();
|
||||
runUniqueObjectTest();
|
||||
|
||||
setupCanvas();
|
||||
runOutputTests();
|
||||
runDrawArraysWithOffsetTest();
|
||||
runVAOInstancingInteractionTest();
|
||||
runANGLECorruptionTest();
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("ANGLE_instanced_arrays") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("ANGLE_instanced_arrays listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("ANGLE_instanced_arrays listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("ANGLE_instanced_arrays not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("ANGLE_instanced_arrays not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runDivisorTestDisabled() {
|
||||
debug("Testing VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE with extension disabled");
|
||||
|
||||
var VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
|
||||
|
||||
gl.getVertexAttrib(0, VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE should not be queryable if extension is disabled");
|
||||
}
|
||||
|
||||
function runDivisorTestEnabled() {
|
||||
debug("Testing VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE with extension enabled");
|
||||
|
||||
shouldBe("ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE", "0x88FE");
|
||||
|
||||
var max_vertex_attribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
|
||||
for (var i = 0; i < max_vertex_attribs; ++i) {
|
||||
var queried_value = gl.getVertexAttrib(i, ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE);
|
||||
if(queried_value == 0){
|
||||
testPassed("Vertex attribute " + i + " must has a default divisor of 0");
|
||||
}
|
||||
else{
|
||||
testFailed("Default divisor of vertex attribute " + i + " should be: 0, returned value was: " + queried_value);
|
||||
}
|
||||
}
|
||||
|
||||
ext.vertexAttribDivisorANGLE(max_vertex_attribs, 2);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "vertexAttribDivisorANGLE index set greater than or equal to MAX_VERTEX_ATTRIBS should be an invalid value");
|
||||
|
||||
ext.vertexAttribDivisorANGLE(max_vertex_attribs-1, 2);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "vertexAttribDivisorANGLE index set less than MAX_VERTEX_ATTRIBS should succeed");
|
||||
|
||||
var queried_value = gl.getVertexAttrib(max_vertex_attribs-1, ext.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE);
|
||||
if(queried_value == 2){
|
||||
testPassed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE matches expecation");
|
||||
}
|
||||
else{
|
||||
testFailed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE should be: 2, returned value was: " + queried_value);
|
||||
}
|
||||
}
|
||||
|
||||
function setupCanvas() {
|
||||
canvas.width = 50; canvas.height = 50;
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
|
||||
program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['aPosition', 'aOffset', 'aColor'], [positionLoc, offsetLoc, colorLoc]);
|
||||
ext = gl.getExtension("ANGLE_instanced_arrays");
|
||||
}
|
||||
|
||||
function runOutputTests() {
|
||||
var instanceCount = 4;
|
||||
|
||||
debug("Testing various draws for valid built-in function behavior");
|
||||
|
||||
var offsets = new Float32Array([
|
||||
-1.0, 1.0,
|
||||
1.0, 1.0,
|
||||
-1.0, -1.0,
|
||||
1.0, -1.0,
|
||||
]);
|
||||
var offsetBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(offsetLoc);
|
||||
gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0);
|
||||
ext.vertexAttribDivisorANGLE(offsetLoc, 1);
|
||||
|
||||
var colors = new Float32Array([
|
||||
1.0, 0.0, 0.0, 1.0, // Red
|
||||
0.0, 1.0, 0.0, 1.0, // Green
|
||||
0.0, 0.0, 1.0, 1.0, // Blue
|
||||
1.0, 1.0, 0.0, 1.0, // Yellow
|
||||
]);
|
||||
var colorBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(colorLoc);
|
||||
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
|
||||
ext.vertexAttribDivisorANGLE(colorLoc, 1);
|
||||
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
|
||||
// Draw 1: Regular drawArrays
|
||||
debug("");
|
||||
debug("Testing drawArrays with non-zero divisor");
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "vertex attrib divisor should affect regular drawArrays when the extension is enabled");
|
||||
wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
|
||||
|
||||
// Draw 2: Draw Non-indexed instances
|
||||
debug("");
|
||||
debug("Testing drawArraysInstancedANGLE");
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// Test drawArraysInstancedANGLE error conditions
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount);
|
||||
wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2, [0, 255, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 255]);
|
||||
wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
|
||||
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, -1);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstancedANGLE cannot have a primcount less than 0");
|
||||
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, -1, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawArraysInstancedANGLE cannot have a count less than 0");
|
||||
|
||||
ext.vertexAttribDivisorANGLE(positionLoc, 1);
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "There must be at least one vertex attribute with a divisor of zero when calling drawArraysInstancedANGLE");
|
||||
ext.vertexAttribDivisorANGLE(positionLoc, 0);
|
||||
|
||||
ext.drawArraysInstancedANGLE(gl.POINTS, 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with POINTS should succeed");
|
||||
ext.drawArraysInstancedANGLE(gl.LINES, 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with LINES should succeed");
|
||||
ext.drawArraysInstancedANGLE(gl.LINE_LIST, 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with LINE_LIST should return succeed");
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLE_LIST, 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE with TRIANGLE_LIST should succeed");
|
||||
|
||||
ext.drawArraysInstancedANGLE(desktopGL['QUAD_STRIP'], 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstancedANGLE with QUAD_STRIP should return INVALID_ENUM");
|
||||
ext.drawArraysInstancedANGLE(desktopGL['QUADS'], 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstancedANGLE with QUADS should return INVALID_ENUM");
|
||||
ext.drawArraysInstancedANGLE(desktopGL['POLYGON'], 0, 6, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstancedANGLE with POLYGON should return INVALID_ENUM");
|
||||
|
||||
debug("");
|
||||
debug("Testing drawArraysInstancedANGLE with param 'first' > 0");
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.setupQuad(gl, {
|
||||
positionLocation: 0,
|
||||
scale: 0.5
|
||||
});
|
||||
var offsetsHalf = new Float32Array([
|
||||
-0.5, 0.5,
|
||||
0.5, 0.5,
|
||||
-0.5, -0.5,
|
||||
0.5, -0.5
|
||||
]);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, offsetsHalf, gl.STATIC_DRAW);
|
||||
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 3, 3, instanceCount);
|
||||
var w = Math.floor(0.25*canvas.width),
|
||||
h = Math.floor(0.25*canvas.height);
|
||||
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 0, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [0, 255, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [0, 0, 255, 255]);
|
||||
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
|
||||
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
wtu.setupIndexedQuad(gl, 1, 0);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
|
||||
|
||||
// Draw 3: Regular drawElements
|
||||
debug("");
|
||||
debug("Testing drawElements with non-zero divisor");
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
// Point to another location in the buffer so that the draw would overflow without the divisor
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 48);
|
||||
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "vertex attrib divisor should affect regular drawElements when the extension is enabled");
|
||||
wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
|
||||
// Restore the vertex attrib pointer
|
||||
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Draw 4: Draw indexed instances
|
||||
debug("");
|
||||
debug("Testing drawElementsInstancedANGLE");
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.checkCanvasRect(gl, 0, canvas.height/2, canvas.width/2, canvas.height/2, [255, 0, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, canvas.width/2, canvas.height/2, canvas.width/2, canvas.height/2, [0, 255, 0, 255]);
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width/2, canvas.height/2, [0, 0, 255, 255]);
|
||||
wtu.checkCanvasRect(gl, canvas.width/2, 0, canvas.width/2, canvas.height/2, [255, 255, 0, 255]);
|
||||
|
||||
// Test drawElementsInstancedANGLE error conditions
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, -1);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstancedANGLE cannot have a primcount less than 0");
|
||||
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLES, -1, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "drawElementsInstancedANGLE cannot have a count less than 0");
|
||||
|
||||
ext.vertexAttribDivisorANGLE(positionLoc, 1);
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "There must be at least one vertex attribute with a divisor of zero when calling drawElementsInstancedANGLE");
|
||||
ext.vertexAttribDivisorANGLE(positionLoc, 0);
|
||||
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with UNSIGNED_BYTE should succeed");
|
||||
|
||||
ext.drawElementsInstancedANGLE(gl.POINTS, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with POINTS should succeed");
|
||||
ext.drawElementsInstancedANGLE(gl.LINES, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with LINES should succeed");
|
||||
ext.drawElementsInstancedANGLE(gl.LINE_LIST, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with LINE_LIST should return succeed");
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLE_LIST, 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawElementsInstancedANGLE with TRIANGLE_LIST should succeed");
|
||||
|
||||
ext.drawElementsInstancedANGLE(desktopGL['QUAD_STRIP'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUAD_STRIP should return INVALID_ENUM");
|
||||
ext.drawElementsInstancedANGLE(desktopGL['QUADS'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUADS should return INVALID_ENUM");
|
||||
ext.drawElementsInstancedANGLE(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with POLYGON should return INVALID_ENUM");
|
||||
}
|
||||
|
||||
function runDrawArraysTest(program, first, count, instanceCount, offset)
|
||||
{
|
||||
// Get the attribute and uniform locations
|
||||
var positionLoc = gl.getAttribLocation(program, "aPosition");
|
||||
var instancePosLoc = gl.getAttribLocation(program, "aInstancePos");
|
||||
var uniformLoc = gl.getUniformLocation(program, "uOffset");
|
||||
|
||||
// Load the vertex positions
|
||||
var positions = new Float32Array([
|
||||
-1, -1,
|
||||
-1, 0,
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
0, -1,
|
||||
-1, -1,
|
||||
|
||||
1, -1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
|
||||
0, 0,
|
||||
0, -1,
|
||||
1, -1,
|
||||
]);
|
||||
var positionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(positionLoc);
|
||||
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Load the instance positions
|
||||
var instancePositions = new Float32Array([
|
||||
0, 0,
|
||||
1, 0
|
||||
]);
|
||||
var instancePositionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, instancePositionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, instancePositions, gl.STATIC_DRAW);
|
||||
gl.enableVertexAttribArray(instancePosLoc);
|
||||
gl.vertexAttribPointer(instancePosLoc, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Enable instancing
|
||||
ext.vertexAttribDivisorANGLE(instancePosLoc, 1);
|
||||
|
||||
// Offset
|
||||
gl.uniform3fv(uniformLoc, offset);
|
||||
|
||||
// Do the instanced draw
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, first, count, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE should succeed");
|
||||
}
|
||||
|
||||
function runDrawArraysWithOffsetTest()
|
||||
{
|
||||
debug("");
|
||||
debug("Testing that the 'first' parameter to drawArraysInstancedANGLE is only an offset into the non-instanced vertex attributes.");
|
||||
// See: http://crbug.com/457269 and http://crbug.com/447140
|
||||
|
||||
var drawArraysProgram = wtu.setupProgram(gl, ["drawArraysTestVertexShader", "drawArraysTestFragmentShader"]);
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
runDrawArraysTest(drawArraysProgram, 0, 6, 2, [0, 0, 0]);
|
||||
|
||||
runDrawArraysTest(drawArraysProgram, 6, 6, 2, [-1, 1, 0]);
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
|
||||
}
|
||||
|
||||
function runUniqueObjectTest()
|
||||
{
|
||||
debug("");
|
||||
debug("Testing that getExtension() returns the same object each time");
|
||||
ext = null;
|
||||
gl.getExtension("ANGLE_instanced_arrays").myProperty = 2;
|
||||
webglHarnessCollectGarbage();
|
||||
shouldBe('gl.getExtension("ANGLE_instanced_arrays").myProperty', '2');
|
||||
}
|
||||
|
||||
function runVAOInstancingInteractionTest()
|
||||
{
|
||||
debug("")
|
||||
debug("Testing that ANGLE_instanced_arrays interacts correctly with OES_vertex_array_object if present");
|
||||
// See: https://github.com/KhronosGroup/WebGL/issues/1228
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
vaoext = gl.getExtension("OES_vertex_array_object");
|
||||
if (!vaoext) {
|
||||
testPassed("No OES_vertex_array_object support -- this is legal");
|
||||
return;
|
||||
}
|
||||
|
||||
testPassed("Successfully enabled OES_vertex_array_object extension");
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
var positions = new Float32Array([
|
||||
0.0, 1.0, // Left quad
|
||||
-1.0, 1.0,
|
||||
-1.0, -1.0,
|
||||
0.0, 1.0,
|
||||
-1.0, -1.0,
|
||||
0.0, -1.0,
|
||||
|
||||
1.0, 1.0, // Right quad
|
||||
0.0, 1.0,
|
||||
0.0, -1.0,
|
||||
1.0, 1.0,
|
||||
0.0, -1.0,
|
||||
1.0, -1.0
|
||||
]);
|
||||
var positionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
|
||||
|
||||
var colors = new Float32Array([
|
||||
1.0, 0.0, 0.0, 1.0, // Red
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
|
||||
0.0, 0.0, 1.0, 1.0, // Blue
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
]);
|
||||
var colorBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
|
||||
|
||||
// Reset the divisor of the default VAO to 0
|
||||
ext.vertexAttribDivisorANGLE(colorLoc, 0);
|
||||
|
||||
// Set up VAO with an attrib divisor
|
||||
var vao1 = vaoext.createVertexArrayOES();
|
||||
vaoext.bindVertexArrayOES(vao1);
|
||||
{
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.enableVertexAttribArray(positionLoc);
|
||||
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.enableVertexAttribArray(colorLoc);
|
||||
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
|
||||
ext.vertexAttribDivisorANGLE(colorLoc, 1);
|
||||
|
||||
gl.vertexAttrib2fv(offsetLoc, [0.0, 0.0]);
|
||||
}
|
||||
vaoext.bindVertexArrayOES(null);
|
||||
|
||||
// Set up VAO with no attrib divisor
|
||||
var vao2 = vaoext.createVertexArrayOES();
|
||||
vaoext.bindVertexArrayOES(vao2);
|
||||
{
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.enableVertexAttribArray(positionLoc);
|
||||
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.enableVertexAttribArray(colorLoc);
|
||||
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
|
||||
// Note that no divisor is set here, which implies that it's 0
|
||||
|
||||
gl.vertexAttrib2fv(offsetLoc, [0.0, 0.0]);
|
||||
}
|
||||
vaoext.bindVertexArrayOES(null);
|
||||
|
||||
debug("");
|
||||
debug("Ensure that Vertex Array Objects retain attrib divisors");
|
||||
|
||||
vaoext.bindVertexArrayOES(vao1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 12);
|
||||
// If the divisor is properly managed by the VAO a single red quad will be drawn
|
||||
wtu.checkCanvas(gl, [255, 0, 0, 255], "entire canvas should be red");
|
||||
|
||||
vaoext.bindVertexArrayOES(vao2);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 12);
|
||||
// If the divisor is properly managed by the VAO a red and blue quad will be drawn.
|
||||
wtu.checkCanvasRects(gl, [
|
||||
wtu.makeCheckRect(0, 0, canvas.width * 0.5, canvas.height, [255, 0, 0, 255], "left half of canvas should be red", 1),
|
||||
wtu.makeCheckRect(canvas.width * 0.5, 0, canvas.width * 0.5, canvas.height, [0, 0, 255, 255], "right half of canvas should be blue", 1)
|
||||
]);
|
||||
|
||||
vaoext.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
function runANGLECorruptionTest()
|
||||
{
|
||||
debug("")
|
||||
debug("Testing to ensure that rendering isn't corrupt due to an ANGLE bug");
|
||||
// See: https://code.google.com/p/angleproject/issues/detail?id=467
|
||||
|
||||
setupCanvas();
|
||||
|
||||
var tolerance = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
|
||||
var instanceCount = 10; // Must be higher than 6
|
||||
var iteration = 0;
|
||||
var totalIterations = 10;
|
||||
|
||||
var offsets = new Float32Array([
|
||||
0.0, 0.0,
|
||||
0.2, 0.0,
|
||||
0.4, 0.0,
|
||||
0.6, 0.0,
|
||||
0.8, 0.0,
|
||||
1.0, 0.0,
|
||||
1.2, 0.0,
|
||||
1.4, 0.0,
|
||||
1.6, 0.0,
|
||||
1.8, 0.0,
|
||||
]);
|
||||
var offsetBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, offsets.byteLength * 2, gl.STATIC_DRAW);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, offsets);
|
||||
gl.enableVertexAttribArray(offsetLoc);
|
||||
gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0);
|
||||
ext.vertexAttribDivisorANGLE(offsetLoc, 1);
|
||||
|
||||
var colors = new Float32Array([
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
1.0, 1.0, 0.0, 1.0,
|
||||
0.0, 1.0, 0.0, 1.0,
|
||||
0.0, 1.0, 1.0, 1.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
1.0, 0.0, 1.0, 1.0,
|
||||
1.0, 0.0, 0.0, 1.0,
|
||||
1.0, 1.0, 0.0, 1.0,
|
||||
0.0, 1.0, 0.0, 1.0,
|
||||
0.0, 1.0, 1.0, 1.0,
|
||||
]);
|
||||
var colorBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, colors.byteLength * 2, gl.STATIC_DRAW);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, colors);
|
||||
gl.enableVertexAttribArray(colorLoc);
|
||||
gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
|
||||
ext.vertexAttribDivisorANGLE(colorLoc, 1);
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
|
||||
function cycleAndTest() {
|
||||
// Update the instanced data buffers outside the accessed range.
|
||||
// This, plus rendering more instances than vertices, triggers the bug.
|
||||
var nullData = new Float32Array(offsets.length);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, offsets.byteLength, nullData);
|
||||
|
||||
nullData = new Float32Array(colors.length);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, colors.byteLength, nullData);
|
||||
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 6, instanceCount);
|
||||
|
||||
// Make sure each color was drawn correctly
|
||||
var i;
|
||||
var passed = true;
|
||||
for (i = 0; i < instanceCount; ++i) {
|
||||
var w = canvas.width / instanceCount;
|
||||
var x = w * i;
|
||||
var color = [colors[(i*4)] * 255, colors[(i*4)+1] * 255, colors[(i*4)+2] * 255, 255]
|
||||
|
||||
wtu.checkCanvasRectColor(
|
||||
gl, x, 0, w, canvas.height, color, tolerance,
|
||||
function() {},
|
||||
function() {
|
||||
passed = false;
|
||||
}, debug);
|
||||
}
|
||||
|
||||
if (passed) {
|
||||
testPassed("Passed test " + iteration + " of " + totalIterations);
|
||||
if (iteration < totalIterations) {
|
||||
++iteration;
|
||||
setTimeout(cycleAndTest, 0);
|
||||
} else {
|
||||
finishTest();
|
||||
}
|
||||
} else {
|
||||
testFailed("Failed test " + iteration + " of " + totalIterations);
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
cycleAndTest();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,248 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL EXT_blend_minmax Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<!-- Shaders to test output -->
|
||||
<script id="outputVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
<script id="outputFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform vec4 uColor;
|
||||
void main() {
|
||||
gl_FragColor = uColor;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the EXT_blend_minmax extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
|
||||
// Use the constant directly when we don't have the extension
|
||||
var MIN_EXT = 0x8007;
|
||||
var MAX_EXT = 0x8008;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
runBlendTestDisabled();
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_blend_minmax");
|
||||
if (!ext) {
|
||||
testPassed("No EXT_blend_minmax support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
debug("");
|
||||
testPassed("Successfully enabled EXT_blend_minmax extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
runBlendTestEnabled();
|
||||
runOutputTests();
|
||||
runUniqueObjectTest();
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("EXT_blend_minmax") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("EXT_blend_minmax listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("EXT_blend_minmax listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("EXT_blend_minmax not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("EXT_blend_minmax not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runBlendTestDisabled() {
|
||||
debug("");
|
||||
debug("Testing blending enums with extension disabled");
|
||||
|
||||
// Set the blend equation to a known-good enum first
|
||||
gl.blendEquation(gl.FUNC_ADD);
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.blendEquation(MIN_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.blendEquation(MAX_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.blendEquationSeparate(MIN_EXT, gl.FUNC_ADD)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_RGB)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.blendEquationSeparate(gl.FUNC_ADD, MIN_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_ALPHA)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.blendEquationSeparate(MAX_EXT, gl.FUNC_ADD)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_RGB)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.blendEquationSeparate(gl.FUNC_ADD, MAX_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_ALPHA)", "gl.FUNC_ADD");
|
||||
}
|
||||
|
||||
function runBlendTestEnabled() {
|
||||
debug("");
|
||||
debug("Testing blending enums with extension enabled");
|
||||
|
||||
shouldBe("ext.MIN_EXT", "0x8007");
|
||||
shouldBe("ext.MAX_EXT", "0x8008");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendEquation(ext.MIN_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION)", "ext.MIN_EXT");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendEquation(ext.MAX_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION)", "ext.MAX_EXT");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendEquationSeparate(ext.MIN_EXT, gl.FUNC_ADD)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_RGB)", "ext.MIN_EXT");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_ALPHA)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendEquationSeparate(gl.FUNC_ADD, ext.MIN_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_RGB)", "gl.FUNC_ADD");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_ALPHA)", "ext.MIN_EXT");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendEquationSeparate(ext.MAX_EXT, gl.FUNC_ADD)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_RGB)", "ext.MAX_EXT");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_ALPHA)", "gl.FUNC_ADD");
|
||||
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.blendEquationSeparate(gl.FUNC_ADD, ext.MAX_EXT)");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_RGB)", "gl.FUNC_ADD");
|
||||
shouldBe("gl.getParameter(gl.BLEND_EQUATION_ALPHA)", "ext.MAX_EXT");
|
||||
}
|
||||
|
||||
function runOutputTests() {
|
||||
var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
|
||||
|
||||
debug("");
|
||||
debug("Testing various draws for valid blending behavior");
|
||||
|
||||
canvas.width = 50; canvas.height = 50;
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.ONE, gl.ONE);
|
||||
|
||||
var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition'], [0]);
|
||||
var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
|
||||
var colorUniform = gl.getUniformLocation(program, "uColor");
|
||||
|
||||
|
||||
// Draw 1
|
||||
gl.blendEquation(ext.MIN_EXT);
|
||||
|
||||
gl.clearColor(0.2, 0.4, 0.6, 0.8);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
gl.uniform4f(colorUniform, 0.8, 0.6, 0.4, 0.2);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [51, 102, 102, 51]);
|
||||
|
||||
// Draw 2:
|
||||
gl.blendEquation(ext.MAX_EXT);
|
||||
|
||||
gl.clearColor(0.2, 0.4, 0.6, 0.8);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
gl.uniform4f(colorUniform, 0.8, 0.6, 0.4, 0.2);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [204, 153, 153, 204]);
|
||||
|
||||
// Draw 3
|
||||
gl.blendEquationSeparate(ext.MIN_EXT, ext.MAX_EXT);
|
||||
|
||||
gl.clearColor(0.2, 0.4, 0.6, 0.8);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
gl.uniform4f(colorUniform, 0.8, 0.6, 0.4, 0.2);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [51, 102, 102, 204]);
|
||||
|
||||
// Draw 4
|
||||
gl.blendEquationSeparate(ext.MAX_EXT, ext.MIN_EXT);
|
||||
|
||||
gl.clearColor(0.2, 0.4, 0.6, 0.8);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
gl.uniform4f(colorUniform, 0.8, 0.6, 0.4, 0.2);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [204, 153, 153, 51]);
|
||||
}
|
||||
|
||||
function runUniqueObjectTest()
|
||||
{
|
||||
debug("");
|
||||
debug("Testing that getExtension() returns the same object each time");
|
||||
ext = null;
|
||||
gl.getExtension("EXT_blend_minmax").myProperty = 2;
|
||||
webglHarnessCollectGarbage();
|
||||
shouldBe('gl.getExtension("EXT_blend_minmax").myProperty', '2');
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,328 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2015 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL EXT_disjoint_timer_query Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the EXT_disjoint_timer_query extension, if it is available.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
var query = null;
|
||||
var query2 = null;
|
||||
var elapsed_query = null;
|
||||
var timestamp_query1 = null;
|
||||
var timestamp_query2 = null;
|
||||
var availability_retry = 500;
|
||||
var timestamp_counter_bits = 0;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
finishTest();
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_disjoint_timer_query");
|
||||
if (!ext) {
|
||||
testPassed("No EXT_disjoint_timer_query support -- this is legal");
|
||||
finishTest();
|
||||
} else {
|
||||
runSanityTests();
|
||||
|
||||
// Clear disjoint value.
|
||||
gl.getParameter(ext.GPU_DISJOINT_EXT);
|
||||
|
||||
runElapsedTimeTest();
|
||||
timestamp_counter_bits = ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT);
|
||||
if (timestamp_counter_bits > 0) {
|
||||
runTimeStampTest();
|
||||
}
|
||||
verifyQueryResultsNotAvailable();
|
||||
|
||||
window.requestAnimationFrame(checkQueryResults);
|
||||
}
|
||||
}
|
||||
|
||||
function runSanityTests() {
|
||||
debug("");
|
||||
debug("Testing timer query expectations");
|
||||
|
||||
shouldBe("ext.QUERY_COUNTER_BITS_EXT", "0x8864");
|
||||
shouldBe("ext.CURRENT_QUERY_EXT", "0x8865");
|
||||
shouldBe("ext.QUERY_RESULT_EXT", "0x8866");
|
||||
shouldBe("ext.QUERY_RESULT_AVAILABLE_EXT", "0x8867");
|
||||
shouldBe("ext.TIME_ELAPSED_EXT", "0x88BF");
|
||||
shouldBe("ext.TIMESTAMP_EXT", "0x8E28");
|
||||
shouldBe("ext.GPU_DISJOINT_EXT", "0x8FBB");
|
||||
|
||||
shouldBe("ext.isQueryEXT(null)", "false");
|
||||
|
||||
shouldBeTrue("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT) === null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeTrue("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
shouldBeTrue("ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.CURRENT_QUERY_EXT) === null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
// Certain drivers set timestamp counter bits to 0 as they don't support timestamps
|
||||
shouldBeTrue("ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30 || " +
|
||||
"ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) === 0");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Testing time elapsed query lifecycle");
|
||||
query = ext.createQueryEXT();
|
||||
shouldBe("ext.isQueryEXT(query)", "false");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query creation must succeed.");
|
||||
shouldThrow("ext.beginQueryEXT(ext.TIMESTAMP_EXT, null)");
|
||||
ext.beginQueryEXT(ext.TIMESTAMP_EXT, query);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Beginning a timestamp query should fail.");
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
|
||||
shouldBe("ext.isQueryEXT(query)", "true");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Beginning an inactive time elapsed query should succeed.");
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to begin an active query should fail.");
|
||||
ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability of an active query should fail.");
|
||||
ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result of an active query should fail.");
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "query");
|
||||
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Ending an active time elapsed query should succeed.");
|
||||
shouldThrow("ext.getQueryObjectEXT(null, ext.QUERY_RESULT_AVAILABLE_EXT)");
|
||||
ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Fetching query result availability after query end should succeed.");
|
||||
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to end an inactive query should fail.");
|
||||
ext.queryCounterEXT(query, ext.TIMESTAMP_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should not be able to use time elapsed query to store a timestamp.");
|
||||
ext.deleteQueryEXT(query);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query deletion must succeed.");
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning a deleted query must fail.");
|
||||
ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability after query deletion should fail.");
|
||||
shouldBe("ext.isQueryEXT(query)", "false");
|
||||
|
||||
debug("");
|
||||
debug("Testing timestamp counter");
|
||||
query = ext.createQueryEXT();
|
||||
shouldThrow("ext.queryCounterEXT(null, ext.TIMESTAMP_EXT)");
|
||||
ext.queryCounterEXT(query, ext.TIMESTAMP_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp counter queries should work.");
|
||||
ext.deleteQueryEXT(query);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Performing parameter sanity checks");
|
||||
gl.getParameter(ext.TIMESTAMP_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter timestamp calls should work.");
|
||||
gl.getParameter(ext.GPU_DISJOINT_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter disjoint calls should work.");
|
||||
|
||||
debug("");
|
||||
debug("Testing current query conditions");
|
||||
query = ext.createQueryEXT();
|
||||
query2 = ext.createQueryEXT();
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "null");
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "query");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Testing failed begin query should not change the current query.");
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query2);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning an elapsed query without ending should fail.");
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "query");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Testing beginning a timestamp query is invalid and should not change the elapsed query.");
|
||||
ext.beginQueryEXT(ext.TIMESTAMP_EXT, query2)
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "query");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Testing timestamp queries end immediately so are never current.");
|
||||
ext.queryCounterEXT(query2, ext.TIMESTAMP_EXT);
|
||||
shouldBe("ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.CURRENT_QUERY_EXT)", "null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Testing ending the query should clear the current query.");
|
||||
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("");
|
||||
debug("Testing beginning a elapsed query using a timestamp query should fail and not affect current query.")
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query2);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Switching query targets should fail.");
|
||||
shouldBe("ext.getQueryEXT(ext.TIME_ELAPSED_EXT, ext.CURRENT_QUERY_EXT)", "null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
ext.deleteQueryEXT(query);
|
||||
ext.deleteQueryEXT(query2);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at end of sanity tests");
|
||||
}
|
||||
|
||||
function runElapsedTimeTest() {
|
||||
debug("");
|
||||
debug("Testing elapsed time query");
|
||||
|
||||
elapsed_query = ext.createQueryEXT();
|
||||
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, elapsed_query);
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Time elapsed query should have no errors");
|
||||
}
|
||||
|
||||
function runTimeStampTest() {
|
||||
debug("");
|
||||
debug("Testing timestamp query");
|
||||
|
||||
timestamp_query1 = ext.createQueryEXT();
|
||||
timestamp_query2 = ext.createQueryEXT();
|
||||
ext.queryCounterEXT(timestamp_query1, ext.TIMESTAMP_EXT);
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
ext.queryCounterEXT(timestamp_query2, ext.TIMESTAMP_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp queries should have no errors");
|
||||
}
|
||||
|
||||
function verifyQueryResultsNotAvailable() {
|
||||
debug("");
|
||||
debug("Verifying queries' results don't become available too early");
|
||||
|
||||
// Verify as best as possible that the implementation doesn't
|
||||
// allow a query's result to become available the same frame, by
|
||||
// spin-looping for some time and ensuring that none of the
|
||||
// queries' results become available.
|
||||
var startTime = Date.now();
|
||||
while (Date.now() - startTime < 2000) {
|
||||
gl.finish();
|
||||
if (ext.getQueryObjectEXT(elapsed_query, ext.QUERY_RESULT_AVAILABLE_EXT)) {
|
||||
testFailed("One of the queries' results became available too early");
|
||||
return;
|
||||
}
|
||||
if (timestamp_counter_bits > 0) {
|
||||
if (ext.getQueryObjectEXT(timestamp_query1, ext.QUERY_RESULT_AVAILABLE_EXT) ||
|
||||
ext.getQueryObjectEXT(timestamp_query2, ext.QUERY_RESULT_AVAILABLE_EXT)) {
|
||||
testFailed("One of the queries' results became available too early");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testPassed("Queries' results didn't become available in a spin loop");
|
||||
}
|
||||
|
||||
function checkQueryResults() {
|
||||
if (availability_retry > 0) {
|
||||
// Make a reasonable attempt to wait for the queries' results to become available.
|
||||
if (!ext.getQueryObjectEXT(elapsed_query, ext.QUERY_RESULT_AVAILABLE_EXT) ||
|
||||
(timestamp_counter_bits > 0 && !ext.getQueryObjectEXT(timestamp_query2, ext.QUERY_RESULT_AVAILABLE_EXT))) {
|
||||
var error = gl.getError();
|
||||
if (error != gl.NO_ERROR) {
|
||||
testFailed("getQueryObjectEXT should have no errors: " + wtu.glEnumToString(gl, error));
|
||||
debug("");
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
availability_retry--;
|
||||
window.requestAnimationFrame(checkQueryResults);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("Testing query results");
|
||||
|
||||
// Make sure queries are available.
|
||||
shouldBe("ext.getQueryObjectEXT(elapsed_query, ext.QUERY_RESULT_AVAILABLE_EXT)", "true");
|
||||
if (timestamp_counter_bits > 0) {
|
||||
shouldBe("ext.getQueryObjectEXT(timestamp_query1, ext.QUERY_RESULT_AVAILABLE_EXT)", "true");
|
||||
shouldBe("ext.getQueryObjectEXT(timestamp_query2, ext.QUERY_RESULT_AVAILABLE_EXT)", "true");
|
||||
}
|
||||
|
||||
var disjoint_value = gl.getParameter(ext.GPU_DISJOINT_EXT);
|
||||
if (disjoint_value) {
|
||||
// Cannot validate results make sense, but this is okay.
|
||||
testPassed("Disjoint triggered.");
|
||||
} else {
|
||||
var elapsed_result = ext.getQueryObjectEXT(elapsed_query, ext.QUERY_RESULT_EXT);
|
||||
if (timestamp_counter_bits > 0) {
|
||||
var timestamp_result1 = ext.getQueryObjectEXT(timestamp_query1, ext.QUERY_RESULT_EXT);
|
||||
var timestamp_result2 = ext.getQueryObjectEXT(timestamp_query2, ext.QUERY_RESULT_EXT);
|
||||
}
|
||||
// Do some basic validity checking of the elapsed time query. There's no way it should
|
||||
// take more than about half a second for a no-op query.
|
||||
var halfSecondInNanos = 0.5 * 1000 * 1000 * 1000;
|
||||
if (elapsed_result < 0 || elapsed_result > halfSecondInNanos) {
|
||||
testFailed("Time elapsed query returned invalid data: " + elapsed_result);
|
||||
} else {
|
||||
testPassed("Time elapsed query results were valid.");
|
||||
}
|
||||
|
||||
if (timestamp_counter_bits > 0) {
|
||||
if (timestamp_result1 <= 0 ||
|
||||
timestamp_result2 <= 0 ||
|
||||
timestamp_result2 <= timestamp_result1) {
|
||||
testFailed("Timestamp queries returned invalid data: timestamp_result1 = " +
|
||||
timestamp_result1 + ", timestamp_result2 = " + timestamp_result2);
|
||||
} else {
|
||||
testPassed("Timestamp query results were valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug("");
|
||||
finishTest();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,312 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL EXT_frag_depth Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<!-- Shaders for testing fragment depth writing -->
|
||||
|
||||
<!-- Shader omitting the required #extension pragma -->
|
||||
<script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
gl_FragDepthEXT = 1.0;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shader to test macro definition -->
|
||||
<script id="macroFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
void main() {
|
||||
#ifdef GL_EXT_frag_depth
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
#else
|
||||
// Error expected
|
||||
#error no GL_EXT_frag_depth;
|
||||
#endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shader with required #extension pragma -->
|
||||
<script id="testFragmentShader" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
precision mediump float;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
gl_FragDepthEXT = 1.0;
|
||||
}
|
||||
</script>
|
||||
<!-- Shaders to link with test fragment shaders -->
|
||||
<script id="goodVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
<!-- Shaders to test output -->
|
||||
<script id="outputVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
<script id="outputFragmentShader" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
precision mediump float;
|
||||
uniform float uDepth;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
gl_FragDepthEXT = uDepth;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the EXT_frag_depth extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
|
||||
// Run all tests once.
|
||||
runAllTests();
|
||||
|
||||
// Run all tests against with a new context to test for any cache issues.
|
||||
debug("");
|
||||
debug("Testing new context to catch cache errors");
|
||||
gl = wtu.create3DContext();
|
||||
ext = null;
|
||||
runAllTests();
|
||||
|
||||
function runAllTests() {
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
runShaderTests(false);
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_frag_depth");
|
||||
if (!ext) {
|
||||
testPassed("No EXT_frag_depth support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled EXT_frag_depth extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
runShaderTests(true);
|
||||
runOutputTests();
|
||||
runUniqueObjectTest();
|
||||
|
||||
// Run deferred link tests.
|
||||
runDeferredLinkTests();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("EXT_frag_depth") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("EXT_frag_depth listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("EXT_frag_depth listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("EXT_frag_depth not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("EXT_frag_depth not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runShaderTests(extensionEnabled) {
|
||||
debug("");
|
||||
debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));
|
||||
|
||||
// Expect the macro shader to succeed ONLY if enabled
|
||||
var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
|
||||
if (extensionEnabled) {
|
||||
if (macroFragmentProgram) {
|
||||
// Expected result
|
||||
testPassed("GL_EXT_frag_depth defined in shaders when extension is enabled");
|
||||
} else {
|
||||
testFailed("GL_EXT_frag_depth not defined in shaders when extension is enabled");
|
||||
}
|
||||
} else {
|
||||
if (macroFragmentProgram) {
|
||||
testFailed("GL_EXT_frag_depth defined in shaders when extension is disabled");
|
||||
} else {
|
||||
testPassed("GL_EXT_frag_depth not defined in shaders when extension disabled");
|
||||
}
|
||||
}
|
||||
|
||||
// Always expect the shader missing the #pragma to fail (whether enabled or not)
|
||||
var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
|
||||
if (missingPragmaFragmentProgram) {
|
||||
testFailed("Shader built-ins allowed without #extension pragma");
|
||||
} else {
|
||||
testPassed("Shader built-ins disallowed without #extension pragma");
|
||||
}
|
||||
|
||||
// Try to compile a shader using the built-ins that should only succeed if enabled
|
||||
var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
|
||||
if (extensionEnabled) {
|
||||
if (testFragmentProgram) {
|
||||
testPassed("Shader built-ins compiled successfully when extension enabled");
|
||||
} else {
|
||||
testFailed("Shader built-ins failed to compile when extension enabled");
|
||||
}
|
||||
} else {
|
||||
if (testFragmentProgram) {
|
||||
testFailed("Shader built-ins compiled successfully when extension disabled");
|
||||
} else {
|
||||
testPassed("Shader built-ins failed to compile when extension disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runOutputTests() {
|
||||
var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
|
||||
|
||||
debug("Testing various draws for valid built-in function behavior");
|
||||
|
||||
canvas.width = 50; canvas.height = 50;
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Enable depth testing with a clearDepth of 0.5
|
||||
// This makes it so that fragments are only rendered when
|
||||
// gl_fragDepthEXT is < 0.5
|
||||
gl.clearDepth(0.5);
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
|
||||
var positionLoc = 0;
|
||||
var texcoordLoc = 1;
|
||||
var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition'], [0]);
|
||||
var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
|
||||
var depthUniform = gl.getUniformLocation(program, "uDepth");
|
||||
|
||||
// Draw 1: Greater than clear depth
|
||||
gl.uniform1f(depthUniform, 1.0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 255, 255, 255]);
|
||||
|
||||
// Draw 2: Less than clear depth
|
||||
gl.uniform1f(depthUniform, 0.0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height, [255, 0, 0, 255]);
|
||||
}
|
||||
|
||||
function runUniqueObjectTest()
|
||||
{
|
||||
debug("Testing that getExtension() returns the same object each time");
|
||||
ext = null;
|
||||
gl.getExtension("EXT_frag_depth").myProperty = 2;
|
||||
webglHarnessCollectGarbage();
|
||||
shouldBe('gl.getExtension("EXT_frag_depth").myProperty', '2');
|
||||
}
|
||||
|
||||
function runDeferredLinkTests() {
|
||||
debug("");
|
||||
debug("Testing deferred shader compilation tests.");
|
||||
|
||||
// Test for compilation failures that are caused by missing extensions
|
||||
// do not succeed if extensions are enabled during linking. This would
|
||||
// only happen for deferred shader compilations.
|
||||
|
||||
// First test if link succeeds with extension enabled.
|
||||
var glEnabled = wtu.create3DContext();
|
||||
var extEnabled = glEnabled.getExtension("EXT_frag_depth");
|
||||
if (!extEnabled) {
|
||||
testFailed("Deferred link test expects the extension to be supported");
|
||||
}
|
||||
|
||||
var vertexShader = wtu.loadShaderFromScript(glEnabled, "goodVertexShader");
|
||||
var fragmentShader = wtu.loadShaderFromScript(glEnabled, "macroFragmentShader");
|
||||
|
||||
if (!vertexShader || !fragmentShader) {
|
||||
testFailed("Could not create good shaders.");
|
||||
return;
|
||||
}
|
||||
|
||||
var program = wtu.setupProgram(glEnabled, [vertexShader, fragmentShader]);
|
||||
|
||||
if (!program) {
|
||||
testFailed("Compilation with extension enabled failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new context to test link failure without extension enabled.
|
||||
var glDeferred = wtu.create3DContext();
|
||||
|
||||
var vertexShader = wtu.loadShaderFromScript(glDeferred, "goodVertexShader", glDeferred.VERTEX_SHADER, undefined, undefined, true);
|
||||
var fragmentShader = wtu.loadShaderFromScript(glDeferred, "macroFragmentShader", glDeferred.FRAGMENT_SHADER, undefined, undefined, true);
|
||||
|
||||
if (vertexShader == null || fragmentShader == null) {
|
||||
testFailed("Could not create shaders.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Shader compilations should have failed due to extensions not enabled.
|
||||
glDeferred.getExtension("EXT_frag_depth");
|
||||
var program = wtu.setupProgram(glDeferred, [vertexShader, fragmentShader]);
|
||||
if (program) {
|
||||
testFailed("Compilation with extension disabled then linking with extension enabled should have failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
testPassed("Compilation with extension disabled then linking with extension enabled.");
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,432 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="16" height="16" style="width: 50px; height: 50px; border: 1px solid black;"></canvas>
|
||||
|
||||
<!-- Shaders to test output -->
|
||||
<script id="vertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 aPosition;
|
||||
void main() {
|
||||
gl_Position = aPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform float uColor;
|
||||
void main() {
|
||||
gl_FragColor = vec4(uColor, uColor, uColor, 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas;
|
||||
var gl;
|
||||
var ext = null;
|
||||
|
||||
var extConstants = {
|
||||
"SRGB_EXT": 0x8C40,
|
||||
"SRGB_ALPHA_EXT": 0x8C42,
|
||||
"SRGB8_ALPHA8_EXT": 0x8C43,
|
||||
"FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT": 0x8210
|
||||
};
|
||||
|
||||
function getExtension() {
|
||||
ext = gl.getExtension("EXT_sRGB");
|
||||
}
|
||||
|
||||
function listsExtension() {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
return (supported.indexOf("EXT_sRGB") >= 0);
|
||||
}
|
||||
|
||||
function toVec3String(val) {
|
||||
if (typeof(val) == 'number') {
|
||||
return toVec3String([val, val, val]);
|
||||
}
|
||||
return '[' + val[0] + ', ' + val[1] + ', ' + val[2] + ']';
|
||||
}
|
||||
|
||||
var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
|
||||
|
||||
function expectResult(target) {
|
||||
wtu.checkCanvasRect(gl,
|
||||
Math.floor(gl.drawingBufferWidth / 2),
|
||||
Math.floor(gl.drawingBufferHeight / 2),
|
||||
1,
|
||||
1,
|
||||
[target, target, target, 255],
|
||||
undefined,
|
||||
e);
|
||||
}
|
||||
|
||||
function createGreysRGBTexture(gl, color, format) {
|
||||
var numPixels = gl.drawingBufferWidth * gl.drawingBufferHeight;
|
||||
var elements;
|
||||
switch (format) {
|
||||
case ext.SRGB_EXT: elements = 3; break;
|
||||
case ext.SRGB_ALPHA_EXT: elements = 4; break;
|
||||
default: return null;
|
||||
}
|
||||
|
||||
var size = numPixels * elements;
|
||||
var buf = new Uint8Array(size);
|
||||
for (var ii = 0; ii < numPixels; ++ii) {
|
||||
var off = ii * elements;
|
||||
buf[off + 0] = color;
|
||||
buf[off + 1] = color;
|
||||
buf[off + 2] = color;
|
||||
if (format == ext.SRGB_ALPHA_EXT) {
|
||||
buf[off + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D,
|
||||
0,
|
||||
format,
|
||||
gl.drawingBufferWidth,
|
||||
gl.drawingBufferHeight,
|
||||
0,
|
||||
format,
|
||||
gl.UNSIGNED_BYTE,
|
||||
buf);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
return tex;
|
||||
}
|
||||
|
||||
function testValidFormat(fn, internalFormat, formatName, enabled) {
|
||||
if (enabled) {
|
||||
fn(internalFormat);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "was able to create type " + formatName);
|
||||
} else {
|
||||
testInvalidFormat(fn, internalFormat, formatName, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
function testInvalidFormat(fn, internalFormat, formatName, enabled) {
|
||||
fn(internalFormat);
|
||||
var err = gl.getError();
|
||||
if (err == gl.NO_ERROR) {
|
||||
testFailed("should NOT be able to create type " + formatName);
|
||||
} else if (err == gl.INVALID_ENUM || err == gl.INVALID_VALUE) {
|
||||
testPassed("not able to create invalid format: " + formatName);
|
||||
}
|
||||
}
|
||||
|
||||
var textureFormatFixture = {
|
||||
desc: "Checking texture formats",
|
||||
create: function(format) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D,
|
||||
0, // level
|
||||
format, // internalFormat
|
||||
gl.drawingBufferWidth, // width
|
||||
gl.drawingBufferHeight, // height
|
||||
0, // border
|
||||
format, // format
|
||||
gl.UNSIGNED_BYTE, // type
|
||||
null); // data
|
||||
},
|
||||
tests: [
|
||||
{
|
||||
desc: "Checking valid formats",
|
||||
fn: testValidFormat,
|
||||
formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
|
||||
},
|
||||
{
|
||||
desc: "Checking invalid formats",
|
||||
fn: testInvalidFormat,
|
||||
formats: [ 'SRGB8_ALPHA8_EXT' ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var renderbufferFormatFixture = {
|
||||
desc: "Checking renderbuffer formats",
|
||||
create: function(format) {
|
||||
var rbo = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER,
|
||||
format,
|
||||
gl.drawingBufferWidth,
|
||||
gl.drawingBufferHeight);
|
||||
},
|
||||
tests: [
|
||||
{
|
||||
desc: "Checking valid formats",
|
||||
fn: testValidFormat,
|
||||
formats: [ 'SRGB8_ALPHA8_EXT' ]
|
||||
},
|
||||
{
|
||||
desc: "Checking invalid formats",
|
||||
fn: testInvalidFormat,
|
||||
formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
description("Test sRGB texture support");
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
canvas = document.getElementById("canvas");
|
||||
gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("");
|
||||
debug("Checking sRGB texture support with extension disabled");
|
||||
|
||||
runFormatTest(textureFormatFixture, false);
|
||||
runFormatTest(renderbufferFormatFixture, false);
|
||||
|
||||
debug("");
|
||||
debug("Checking sRGB texture support");
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("EXT_sRGB");
|
||||
|
||||
if (!ext) {
|
||||
testPassed("No EXT_sRGB support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
finishTest();
|
||||
} else {
|
||||
testPassed("Successfully enabled EXT_sRGB extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
|
||||
runConstantsTest();
|
||||
runFormatTest(textureFormatFixture, true);
|
||||
runFormatTest(renderbufferFormatFixture, true);
|
||||
runTextureReadConversionTest();
|
||||
runFramebufferTextureConversionTest(ext.SRGB_EXT);
|
||||
runFramebufferTextureConversionTest(ext.SRGB_ALPHA_EXT);
|
||||
runFramebufferRenderbufferConversionTest();
|
||||
runLoadFromImageTest(function() {
|
||||
finishTest();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function runConstantsTest() {
|
||||
debug("");
|
||||
debug("Checking extension constants values");
|
||||
|
||||
for (var constant in extConstants) {
|
||||
if (constant in ext) {
|
||||
if (extConstants[constant] != ext[constant]) {
|
||||
testFailed("Value of " + constant + " should be: " + extConstants[constant] + ", was: " + ext[constant]);
|
||||
} else {
|
||||
testPassed("Value of " + constant + " was expected value: " + extConstants[constant]);
|
||||
}
|
||||
} else {
|
||||
testFailed(constant + " not found in extension object");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
if (listsExtension()) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("EXT_sRGB listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("EXT_sRGB listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("EXT_sRGB not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("EXT_sRGB not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runFormatTest(fixture, enabled) {
|
||||
debug("");
|
||||
debug(fixture.desc);
|
||||
|
||||
for (var tt = 0; tt < fixture.tests.length; ++tt) {
|
||||
var test = fixture.tests[tt];
|
||||
debug(test.desc);
|
||||
|
||||
for (var ii = 0; ii < test.formats.length; ++ii) {
|
||||
var formatName = test.formats[ii];
|
||||
test.fn(fixture.create, extConstants[formatName], "ext." + formatName, enabled);
|
||||
}
|
||||
|
||||
if (tt != fixture.tests.length - 1)
|
||||
debug("");
|
||||
}
|
||||
}
|
||||
|
||||
function runTextureReadConversionTest() {
|
||||
debug("");
|
||||
debug("Test the conversion of colors from sRGB to linear on texture read");
|
||||
|
||||
// Draw
|
||||
var conversions = [
|
||||
[ 0, 0 ],
|
||||
[ 63, 13 ],
|
||||
[ 127, 54 ],
|
||||
[ 191, 133 ],
|
||||
[ 255, 255 ]
|
||||
];
|
||||
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
gl.uniform1i(gl.getUniformLocation(program, "tex"), 0);
|
||||
|
||||
for (var ii = 0; ii < conversions.length; ii++) {
|
||||
var tex = createGreysRGBTexture(gl, conversions[ii][0], ext.SRGB_EXT);
|
||||
wtu.drawUnitQuad(gl);
|
||||
expectResult(conversions[ii][1]);
|
||||
}
|
||||
}
|
||||
|
||||
function runFramebufferTextureConversionTest(format) {
|
||||
var formatString;
|
||||
var validFormat;
|
||||
switch (format) {
|
||||
case ext.SRGB_EXT: formatString = "sRGB"; validFormat = false; break;
|
||||
case ext.SRGB_ALPHA_EXT: formatString = "sRGB_ALPHA"; validFormat = true; break;
|
||||
default: return null;
|
||||
}
|
||||
debug("");
|
||||
debug("Test " + formatString + " framebuffer attachments." + (validFormat ? "" : " (Invalid)"));
|
||||
|
||||
var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
|
||||
var tex = createGreysRGBTexture(gl, 0, format);
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
|
||||
|
||||
if (validFormat) {
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
debug("");
|
||||
debug("Test the conversion of colors from linear to " + formatString + " on framebuffer (texture) write");
|
||||
|
||||
// Draw
|
||||
var conversions = [
|
||||
[ 0, 0 ],
|
||||
[ 13, 63 ],
|
||||
[ 54, 127 ],
|
||||
[ 133, 191 ],
|
||||
[ 255, 255 ]
|
||||
];
|
||||
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
|
||||
for (var ii = 0; ii < conversions.length; ii++) {
|
||||
gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
|
||||
wtu.drawUnitQuad(gl, [0, 0, 0, 0]);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
expectResult(conversions[ii][1]);
|
||||
}
|
||||
} else {
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
|
||||
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
gl.uniform1f(gl.getUniformLocation(program, "uColor"), 0.5);
|
||||
wtu.drawUnitQuad(gl, [0, 0, 0, 0]);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
|
||||
}
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
function runFramebufferRenderbufferConversionTest() {
|
||||
debug("");
|
||||
debug("Test the conversion of colors from linear to sRGB on framebuffer (renderbuffer) write");
|
||||
|
||||
function createsRGBFramebuffer(gl, width, height) {
|
||||
var rbo = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, ext.SRGB8_ALPHA8_EXT, width, height);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
|
||||
gl.RENDERBUFFER, rbo);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
return fbo;
|
||||
}
|
||||
|
||||
// Draw
|
||||
var conversions = [
|
||||
[ 0, 0 ],
|
||||
[ 13, 63 ],
|
||||
[ 54, 127 ],
|
||||
[ 133, 191 ],
|
||||
[ 255, 255 ]
|
||||
];
|
||||
|
||||
var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
var fbo = createsRGBFramebuffer(gl, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
|
||||
for (var ii = 0; ii < conversions.length; ii++) {
|
||||
gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
|
||||
wtu.drawUnitQuad(gl, [0, 0, 0, 0]);
|
||||
expectResult(conversions[ii][1]);
|
||||
}
|
||||
}
|
||||
|
||||
function runLoadFromImageTest(callback) {
|
||||
debug("");
|
||||
debug("Tests to ensure that SRGB textures can successfully use image elements as their source");
|
||||
|
||||
var img = wtu.makeImage("../../resources/gray-1024x1024.jpg", function() {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, ext.SRGB_EXT, ext.SRGB_EXT, gl.UNSIGNED_BYTE, img);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, ext.SRGB_ALPHA_EXT, ext.SRGB_ALPHA_EXT, gl.UNSIGNED_BYTE, img);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
callback();
|
||||
}, function() {
|
||||
testFailed("Image could not be loaded");
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,364 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL EXT_shader_texture_lod Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/desktop-gl-constants.js"></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 256px; height: 256px;"> </canvas>
|
||||
<canvas id="canvas2" style="width: 256px; height: 256px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<!-- Shaders for testing texture LOD functions -->
|
||||
|
||||
<!-- Shader omitting the required #extension pragma -->
|
||||
<script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec2 texCoord0v;
|
||||
uniform float lod;
|
||||
uniform sampler2D tex;
|
||||
void main() {
|
||||
vec4 color = texture2DLodEXT(tex, texCoord0v, lod);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shader to test macro definition -->
|
||||
<script id="macroFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
void main() {
|
||||
#ifdef GL_EXT_shader_texture_lod
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
#else
|
||||
// Error expected
|
||||
#error no GL_EXT_shader_texture_lod;
|
||||
#endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shader with required #extension pragma -->
|
||||
<script id="testFragmentShader" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_shader_texture_lod : enable
|
||||
precision mediump float;
|
||||
varying vec2 texCoord0v;
|
||||
uniform float lod;
|
||||
uniform sampler2D tex;
|
||||
void main() {
|
||||
vec4 color = texture2DLodEXT(tex, texCoord0v, lod);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shaders to link with test fragment shaders -->
|
||||
<script id="goodVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
attribute vec2 texCoord0;
|
||||
varying vec2 texCoord0v;
|
||||
void main() {
|
||||
texCoord0v = texCoord0;
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shaders to test output -->
|
||||
<script id="outputVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
attribute vec2 texCoord0;
|
||||
varying vec2 texCoord0v;
|
||||
void main() {
|
||||
texCoord0v = texCoord0;
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
<script id="outputFragmentShader" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_shader_texture_lod : require
|
||||
precision mediump float;
|
||||
varying vec2 texCoord0v;
|
||||
uniform float lod;
|
||||
uniform sampler2D tex;
|
||||
void main() {
|
||||
vec4 color = texture2DLodEXT(tex, texCoord0v, lod);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
description("This test verifies the functionality of the EXT_shader_texture_lod extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
|
||||
// Run all tests once.
|
||||
runAllTests();
|
||||
|
||||
// Run all tests against with a new context to test for any cache issues.
|
||||
debug("");
|
||||
debug("Testing new context to catch cache errors");
|
||||
var canvas2 = document.getElementById("canvas2");
|
||||
gl = wtu.create3DContext(canvas2);
|
||||
ext = null;
|
||||
runAllTests();
|
||||
|
||||
function runAllTests() {
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
// Run tests with extension disabled
|
||||
runShaderTests(false);
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("EXT_shader_texture_lod");
|
||||
if (!ext) {
|
||||
testPassed("No EXT_shader_texture_lod support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled EXT_shader_texture_lod extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
runShaderTests(true);
|
||||
runOutputTests();
|
||||
runUniqueObjectTest();
|
||||
runReferenceCycleTest();
|
||||
|
||||
// Run deferred link tests.
|
||||
runDeferredLinkTests();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("EXT_shader_texture_lod") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("EXT_shader_texture_lod listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("EXT_shader_texture_lod listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("EXT_shader_texture_lod not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("EXT_shader_texture_lod not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runShaderTests(extensionEnabled) {
|
||||
debug("");
|
||||
debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));
|
||||
|
||||
// Expect the macro shader to succeed ONLY if enabled
|
||||
var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
|
||||
if (extensionEnabled) {
|
||||
if (macroFragmentProgram) {
|
||||
// Expected result
|
||||
testPassed("GL_EXT_shader_texture_lod defined in shaders when extension is enabled");
|
||||
} else {
|
||||
testFailed("GL_EXT_shader_texture_lod not defined in shaders when extension is enabled");
|
||||
}
|
||||
} else {
|
||||
if (macroFragmentProgram) {
|
||||
testFailed("GL_EXT_shader_texture_lod defined in shaders when extension is disabled");
|
||||
} else {
|
||||
testPassed("GL_EXT_shader_texture_lod not defined in shaders when extension disabled");
|
||||
}
|
||||
}
|
||||
|
||||
// Always expect the shader missing the #pragma to fail (whether enabled or not)
|
||||
var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
|
||||
if (missingPragmaFragmentProgram) {
|
||||
testFailed("Shader built-ins allowed without #extension pragma");
|
||||
} else {
|
||||
testPassed("Shader built-ins disallowed without #extension pragma");
|
||||
}
|
||||
|
||||
// Try to compile a shader using the built-ins that should only succeed if enabled
|
||||
var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
|
||||
if (extensionEnabled) {
|
||||
if (testFragmentProgram) {
|
||||
testPassed("Shader built-ins compiled successfully when extension enabled");
|
||||
} else {
|
||||
testFailed("Shader built-ins failed to compile when extension enabled");
|
||||
}
|
||||
} else {
|
||||
if (testFragmentProgram) {
|
||||
testFailed("Shader built-ins compiled successfully when extension disabled");
|
||||
} else {
|
||||
testPassed("Shader built-ins failed to compile when extension disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runOutputTests() {
|
||||
debug("");
|
||||
debug("Testing various draws for valid built-in function behavior");
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
|
||||
var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition', 'texCoord0'], [0, 1]);
|
||||
var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
|
||||
|
||||
var colors = [
|
||||
{name: 'red', color:[255, 0, 0, 255]},
|
||||
{name: 'green', color:[0, 255, 0, 255]},
|
||||
{name: 'blue', color:[0, 0, 255, 255]},
|
||||
{name: 'yellow', color:[255, 255, 0, 255]},
|
||||
{name: 'magenta', color:[255, 0, 255, 255]},
|
||||
{name: 'cyan', color:[0, 255, 255, 255]},
|
||||
{name: 'pink', color:[255, 128, 128, 255]},
|
||||
{name: 'gray', color:[128, 128, 128, 255]},
|
||||
{name: 'light green', color:[128, 255, 128, 255]},
|
||||
];
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
|
||||
for (var ii = 0; ii < colors.length; ++ii) {
|
||||
var color = colors[ii];
|
||||
var size = Math.pow(2, colors.length - ii - 1);
|
||||
wtu.fillTexture(gl, tex, size, size, color.color, ii);
|
||||
}
|
||||
|
||||
var loc = gl.getUniformLocation(program, "lod");
|
||||
|
||||
for (var ii = 0; ii < colors.length; ++ii) {
|
||||
gl.uniform1f(loc, ii);
|
||||
var color = colors[ii];
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvas(
|
||||
gl, color.color,
|
||||
"256x256 texture drawn to 256x256 dest with lod = " + ii +
|
||||
" should be " + color.name);
|
||||
}
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
}
|
||||
|
||||
function runUniqueObjectTest()
|
||||
{
|
||||
debug("");
|
||||
debug("Testing that getExtension() returns the same object each time");
|
||||
ext = null;
|
||||
gl.getExtension("EXT_shader_texture_lod").myProperty = 2;
|
||||
webglHarnessCollectGarbage();
|
||||
shouldBe('gl.getExtension("EXT_shader_texture_lod").myProperty', '2');
|
||||
}
|
||||
|
||||
function runReferenceCycleTest()
|
||||
{
|
||||
// create some reference cycles. The goal is to see if they cause leaks. The point is that
|
||||
// some browser test runners have instrumentation to detect leaked refcounted objects.
|
||||
debug("");
|
||||
debug("Testing reference cycles between context and extension objects");
|
||||
var ext = gl.getExtension("EXT_shader_texture_lod");
|
||||
|
||||
// create cycle between extension and context, since the context has to hold a reference to the extension
|
||||
ext.context = gl;
|
||||
|
||||
// create a self-cycle on the extension object
|
||||
ext.ext = ext;
|
||||
}
|
||||
|
||||
function runDeferredLinkTests() {
|
||||
debug("");
|
||||
debug("Testing deferred shader compilation tests.");
|
||||
|
||||
// Test for compilation failures that are caused by missing extensions
|
||||
// do not succeed if extensions are enabled during linking. This would
|
||||
// only happen for deferred shader compilations.
|
||||
|
||||
// First test if link succeeds with extension enabled.
|
||||
var glEnabled = wtu.create3DContext();
|
||||
var extEnabled = glEnabled.getExtension("EXT_shader_texture_lod");
|
||||
if (!extEnabled) {
|
||||
testFailed("Deferred link test expects the extension to be supported");
|
||||
}
|
||||
|
||||
var vertexShader = wtu.loadShaderFromScript(glEnabled, "goodVertexShader");
|
||||
var fragmentShader = wtu.loadShaderFromScript(glEnabled, "macroFragmentShader");
|
||||
|
||||
if (!vertexShader || !fragmentShader) {
|
||||
testFailed("Could not create good shaders.");
|
||||
return;
|
||||
}
|
||||
|
||||
var program = wtu.setupProgram(glEnabled, [vertexShader, fragmentShader]);
|
||||
|
||||
if (!program) {
|
||||
testFailed("Compilation with extension enabled failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new context to test link failure without extension enabled.
|
||||
var glDeferred = wtu.create3DContext();
|
||||
|
||||
var vertexShader = wtu.loadShaderFromScript(glDeferred, "goodVertexShader", glDeferred.VERTEX_SHADER, undefined, undefined, true);
|
||||
var fragmentShader = wtu.loadShaderFromScript(glDeferred, "macroFragmentShader", glDeferred.FRAGMENT_SHADER, undefined, undefined, true);
|
||||
|
||||
if (vertexShader == null || fragmentShader == null) {
|
||||
testFailed("Could not create shaders.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Shader compilations should have failed due to extensions not enabled.
|
||||
glDeferred.getExtension("EXT_shader_texture_lod");
|
||||
var program = wtu.setupProgram(glDeferred, [vertexShader, fragmentShader]);
|
||||
if (program) {
|
||||
testFailed("Compilation with extension disabled then linking with extension enabled should have failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
testPassed("Compilation with extension disabled then linking with extension enabled.");
|
||||
}
|
||||
|
||||
debug("");
|
||||
successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,192 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL EXT_texture_filter_anisotropic Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the EXT_texture_filter_anisotropic extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
// Run tests with extension disabled
|
||||
runHintTestDisabled();
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_texture_filter_anisotropic");
|
||||
|
||||
if (!ext) {
|
||||
testPassed("No EXT_texture_filter_anisotropic support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled EXT_texture_filter_anisotropic extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
runHintTestEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
if (wtu.getSupportedExtensionWithKnownPrefixes(gl, "EXT_texture_filter_anisotropic") !== undefined) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("EXT_texture_filter_anisotropic listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("EXT_texture_filter_anisotropic listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("EXT_texture_filter_anisotropic not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("EXT_texture_filter_anisotropic not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runHintTestDisabled() {
|
||||
debug("Testing MAX_TEXTURE_MAX_ANISOTROPY_EXT with extension disabled");
|
||||
|
||||
var MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
|
||||
gl.getParameter(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "MAX_TEXTURE_MAX_ANISOTROPY_EXT should not be queryable if extension is disabled");
|
||||
|
||||
debug("Testing TEXTURE_MAX_ANISOTROPY_EXT with extension disabled");
|
||||
var TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
gl.getTexParameter(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY_EXT should not be queryable if extension is disabled");
|
||||
|
||||
gl.texParameterf(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT, 1);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY_EXT should not be settable if extension is disabled");
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY_EXT, 1);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY_EXT should not be settable if extension is disabled");
|
||||
|
||||
gl.deleteTexture(texture);
|
||||
}
|
||||
|
||||
function runHintTestEnabled() {
|
||||
debug("Testing MAX_TEXTURE_MAX_ANISOTROPY_EXT with extension enabled");
|
||||
|
||||
shouldBe("ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT", "0x84FF");
|
||||
|
||||
var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "MAX_TEXTURE_MAX_ANISOTROPY_EXT query should succeed if extension is enabled");
|
||||
|
||||
if(max_anisotropy >= 2){
|
||||
testPassed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY_EXT is 2.0");
|
||||
}
|
||||
else{
|
||||
testFailed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY_EXT is 2.0, returned values was: " + max_anisotropy);
|
||||
}
|
||||
|
||||
// TODO make a texture and verify initial value == 1 and setting to less than 1 is invalid value
|
||||
|
||||
debug("Testing TEXTURE_MAX_ANISOTROPY_EXT with extension disabled");
|
||||
shouldBe("ext.TEXTURE_MAX_ANISOTROPY_EXT", "0x84FE");
|
||||
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "TEXTURE_MAX_ANISOTROPY_EXT query should succeed if extension is enabled");
|
||||
|
||||
if(queried_value == 1){
|
||||
testPassed("Initial value of TEXTURE_MAX_ANISOTROPY_EXT is 1.0");
|
||||
}
|
||||
else{
|
||||
testFailed("Initial value of TEXTURE_MAX_ANISOTROPY_EXT should be 1.0, returned value was: " + queried_value);
|
||||
}
|
||||
|
||||
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameterf TEXTURE_MAX_ANISOTROPY_EXT set to < 1 should be an invalid value");
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameteri TEXTURE_MAX_ANISOTROPY_EXT set to < 1 should be an invalid value");
|
||||
|
||||
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY_EXT set to >= 2 should succeed");
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameteri TEXTURE_MAX_ANISOTROPY_EXT set to >= 2 should succeed");
|
||||
|
||||
var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
if(queried_value == max_anisotropy){
|
||||
testPassed("Set value of TEXTURE_MAX_ANISOTROPY_EXT matches expecation");
|
||||
}
|
||||
else{
|
||||
testFailed("Set value of TEXTURE_MAX_ANISOTROPY_EXT should be: " + max_anisotropy + " , returned value was: " + queried_value);
|
||||
}
|
||||
|
||||
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, 1.5);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY_EXT set to 1.5 should succeed");
|
||||
|
||||
queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
if(queried_value == 1.5){
|
||||
testPassed("Set value of TEXTURE_MAX_ANISOTROPY_EXT matches expecation");
|
||||
}
|
||||
else{
|
||||
testFailed("Set value of TEXTURE_MAX_ANISOTROPY_EXT should be: " + 1.5 + " , returned value was: " + queried_value);
|
||||
}
|
||||
|
||||
|
||||
gl.deleteTexture(texture);
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,122 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Extension Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
var pseudoRandom = (function() {
|
||||
var seed = 3;
|
||||
return function() {
|
||||
seed = (seed * 11 + 17) % 25;
|
||||
return seed / 25;
|
||||
};
|
||||
})();
|
||||
|
||||
var randomizeCase = function(str) {
|
||||
var newChars = [];
|
||||
for (var ii = 0; ii < str.length; ++ii) {
|
||||
var c = str.substr(ii, 1);
|
||||
var m = (pseudoRandom() > 0.5) ? c.toLowerCase() : c.toUpperCase();
|
||||
newChars.push(m);
|
||||
}
|
||||
return newChars.join("");
|
||||
};
|
||||
|
||||
description();
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
|
||||
var ii;
|
||||
|
||||
debug("check every extension advertised can be enabled");
|
||||
debug("");
|
||||
var extensionNames = gl.getSupportedExtensions();
|
||||
var extensionNamesLower = [];
|
||||
for (ii = 0; ii < extensionNames.length; ++ii) {
|
||||
extensionNamesLower.push(extensionNames[ii].toLowerCase());
|
||||
}
|
||||
|
||||
for (ii = 0; ii < extensionNames.length; ++ii) {
|
||||
var originalName = extensionNames[ii];
|
||||
var mixedName = randomizeCase(originalName);
|
||||
var extension = gl.getExtension(mixedName);
|
||||
assertMsg(extension, "able to get " + originalName + " as " + mixedName);
|
||||
if (extension) {
|
||||
var kTestString = "this is a test";
|
||||
var kTestNumber = 123;
|
||||
var kTestFunction = function() { };
|
||||
var kTestObject = { };
|
||||
extension.testStringProperty = kTestString;
|
||||
extension.testNumberProperty = kTestNumber;
|
||||
extension.testFunctionProperty = kTestFunction;
|
||||
extension.testObjectProperty = kTestObject;
|
||||
webglHarnessCollectGarbage();
|
||||
var extension2 = gl.getExtension(originalName);
|
||||
assertMsg(
|
||||
extension === extension2,
|
||||
"calling getExtension twice for the same extension returns the same object");
|
||||
assertMsg(
|
||||
extension2.testStringProperty === kTestString &&
|
||||
extension2.testFunctionProperty === kTestFunction &&
|
||||
extension2.testObjectProperty === kTestObject &&
|
||||
extension2.testNumberProperty === kTestNumber,
|
||||
"object returned by 2nd call to getExtension has same properties");
|
||||
|
||||
var prefixedVariants = wtu.getExtensionPrefixedNames(originalName);
|
||||
for (var jj = 0; jj < prefixedVariants.length; ++jj) {
|
||||
assertMsg(
|
||||
gl.getExtension(prefixedVariants[jj]) === null ||
|
||||
extensionNamesLower.indexOf(prefixedVariants[jj].toLowerCase()) !== -1,
|
||||
"getExtension('" + prefixedVariants[jj] + "') returns an object only if the name is returned by getSupportedExtensions");
|
||||
}
|
||||
}
|
||||
debug("");
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,451 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL OES_element_index_uint Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
|
||||
<script id="vs" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
attribute vec4 vColor;
|
||||
varying vec4 color;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
color = vColor;
|
||||
}
|
||||
</script>
|
||||
<script id="fs" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec4 color;
|
||||
void main() {
|
||||
gl_FragColor = color;
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the OES_element_index_uint extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = null;
|
||||
var ext = null;
|
||||
var canvas = null;
|
||||
|
||||
// Test both STATIC_DRAW and DYNAMIC_DRAW as a regression test
|
||||
// for a bug in ANGLE which has since been fixed.
|
||||
for (var ii = 0; ii < 2; ++ii) {
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.width = 50;
|
||||
canvas.height = 50;
|
||||
|
||||
gl = wtu.create3DContext(canvas);
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
var drawType = (ii == 0) ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW;
|
||||
debug("Testing " + ((ii == 0) ? "STATIC_DRAW" : "DYNAMIC_DRAW"));
|
||||
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("OES_element_index_uint");
|
||||
if (!ext) {
|
||||
testPassed("No OES_element_index_uint support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled OES_element_index_uint extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
runDrawTests(drawType);
|
||||
|
||||
// These tests are tweaked duplicates of the buffers/index-validation* tests
|
||||
// using unsigned int indices to ensure that behavior remains consistent
|
||||
runIndexValidationTests(drawType);
|
||||
runCopiesIndicesTests(drawType);
|
||||
runResizedBufferTests(drawType);
|
||||
runVerifiesTooManyIndicesTests(drawType);
|
||||
runCrashWithBufferSubDataTests(drawType);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("OES_element_index_uint") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("OES_element_index_uint listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("OES_element_index_uint listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("OES_element_index_uint not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("OES_element_index_uint not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runDrawTests(drawType) {
|
||||
debug("Test that draws with unsigned integer indices produce the expected results");
|
||||
|
||||
canvas.width = 50; canvas.height = 50;
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
|
||||
var program = wtu.setupSimpleColorProgram(gl);
|
||||
|
||||
function setupDraw(s) {
|
||||
// Create a vertex buffer that cannot be fully indexed via shorts
|
||||
var quadArrayLen = 65537 * 3;
|
||||
var quadArray = new Float32Array(quadArrayLen);
|
||||
|
||||
// Leave all but the last 4 values zero-ed out
|
||||
var idx = quadArrayLen - 12;
|
||||
|
||||
// Initialized the last 4 values to a quad
|
||||
quadArray[idx++] = 1.0 * s;
|
||||
quadArray[idx++] = 1.0 * s;
|
||||
quadArray[idx++] = 0.0;
|
||||
|
||||
quadArray[idx++] = -1.0 * s;
|
||||
quadArray[idx++] = 1.0 * s;
|
||||
quadArray[idx++] = 0.0;
|
||||
|
||||
quadArray[idx++] = -1.0 * s;
|
||||
quadArray[idx++] = -1.0 * s;
|
||||
quadArray[idx++] = 0.0;
|
||||
|
||||
quadArray[idx++] = 1.0 * s;
|
||||
quadArray[idx++] = -1.0 * s;
|
||||
quadArray[idx++] = 0.0;
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, quadArray, drawType);
|
||||
|
||||
// Create an unsigned int index buffer that indexes the last 4 vertices
|
||||
var baseIndex = (quadArrayLen / 3) - 4;
|
||||
|
||||
var indexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([
|
||||
baseIndex + 0,
|
||||
baseIndex + 1,
|
||||
baseIndex + 2,
|
||||
baseIndex + 2,
|
||||
baseIndex + 3,
|
||||
baseIndex + 0]), drawType);
|
||||
|
||||
var opt_positionLocation = 0;
|
||||
gl.enableVertexAttribArray(opt_positionLocation);
|
||||
gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
|
||||
};
|
||||
function testPixel(blackList, whiteList) {
|
||||
function testList(list, expected) {
|
||||
for (var n = 0; n < list.length; n++) {
|
||||
var l = list[n];
|
||||
var x = -Math.floor(l * canvas.width / 2) + canvas.width / 2;
|
||||
var y = -Math.floor(l * canvas.height / 2) + canvas.height / 2;
|
||||
wtu.checkCanvasRect(gl, x, y, 1, 1, [expected, expected, expected],
|
||||
"Draw should pass", 2);
|
||||
}
|
||||
}
|
||||
testList(blackList, 0);
|
||||
testList(whiteList, 255);
|
||||
};
|
||||
function verifyDraw(s) {
|
||||
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
wtu.setFloatDrawColor(gl, [0.0, 0.0, 0.0, 1.0]);
|
||||
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, 0);
|
||||
|
||||
var blackList = [];
|
||||
var whiteList = [];
|
||||
var points = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0];
|
||||
for (var n = 0; n < points.length; n++) {
|
||||
if (points[n] <= s) {
|
||||
blackList.push(points[n]);
|
||||
} else {
|
||||
whiteList.push(points[n]);
|
||||
}
|
||||
}
|
||||
testPixel(blackList, whiteList);
|
||||
};
|
||||
|
||||
setupDraw(0.5);
|
||||
verifyDraw(0.5);
|
||||
}
|
||||
|
||||
function runIndexValidationTests(drawType) {
|
||||
description("Tests that index validation verifies the correct number of indices");
|
||||
|
||||
function sizeInBytes(type) {
|
||||
switch (type) {
|
||||
case gl.BYTE:
|
||||
case gl.UNSIGNED_BYTE:
|
||||
return 1;
|
||||
case gl.SHORT:
|
||||
case gl.UNSIGNED_SHORT:
|
||||
return 2;
|
||||
case gl.INT:
|
||||
case gl.UNSIGNED_INT:
|
||||
case gl.FLOAT:
|
||||
return 4;
|
||||
default:
|
||||
throw "unknown type";
|
||||
}
|
||||
}
|
||||
|
||||
var program = wtu.loadStandardProgram(gl);
|
||||
|
||||
// 3 vertices => 1 triangle, interleaved data
|
||||
var dataComplete = new Float32Array([0, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1, 1,
|
||||
0, 0, 1]);
|
||||
var dataIncomplete = new Float32Array([0, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 0, 0, 1,
|
||||
0, 0, 1,
|
||||
1, 1, 1, 1]);
|
||||
var indices = new Uint32Array([0, 1, 2]);
|
||||
|
||||
debug("Testing with valid indices");
|
||||
|
||||
var bufferComplete = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, bufferComplete);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, dataComplete, drawType);
|
||||
var elements = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elements);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
|
||||
gl.useProgram(program);
|
||||
var vertexLoc = gl.getAttribLocation(program, "a_vertex");
|
||||
var normalLoc = gl.getAttribLocation(program, "a_normal");
|
||||
gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
|
||||
gl.enableVertexAttribArray(vertexLoc);
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
debug("Testing with out-of-range indices");
|
||||
|
||||
var bufferIncomplete = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, bufferIncomplete);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, dataIncomplete, drawType);
|
||||
gl.vertexAttribPointer(vertexLoc, 4, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 0);
|
||||
gl.enableVertexAttribArray(vertexLoc);
|
||||
gl.disableVertexAttribArray(normalLoc);
|
||||
debug("Enable vertices, valid");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
debug("Enable normals, out-of-range");
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
|
||||
'gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
|
||||
debug("Test with enabled attribute that does not belong to current program");
|
||||
|
||||
gl.disableVertexAttribArray(normalLoc);
|
||||
var extraLoc = Math.max(vertexLoc, normalLoc) + 1;
|
||||
gl.enableVertexAttribArray(extraLoc);
|
||||
debug("Enable an extra attribute with null");
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||
debug("Enable an extra attribute with insufficient data buffer");
|
||||
gl.vertexAttribPointer(extraLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
debug("Pass large negative index to vertexAttribPointer");
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), -2000000000 * sizeInBytes(gl.FLOAT));
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
}
|
||||
|
||||
function runCopiesIndicesTests(drawType) {
|
||||
debug("Test that client data is always copied during bufferData and bufferSubData calls");
|
||||
|
||||
var program = wtu.loadStandardProgram(gl);
|
||||
|
||||
gl.useProgram(program);
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
// 4 vertices -> 2 triangles
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), drawType);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
var indexObject = gl.createBuffer();
|
||||
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
var indices = new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
|
||||
var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
|
||||
"gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
indices[0] = 2;
|
||||
indices[5] = 1;
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
}
|
||||
|
||||
function runResizedBufferTests(drawType) {
|
||||
debug("Test that updating the size of a vertex buffer is properly noticed by the WebGL implementation.");
|
||||
|
||||
var program = wtu.setupProgram(gl, ["vs", "fs"], ["vPosition", "vColor"]);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after initialization");
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
|
||||
[-1,1,0, 1,1,0, -1,-1,0,
|
||||
-1,-1,0, 1,1,0, 1,-1,0]), drawType);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex setup");
|
||||
|
||||
var texCoordObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(
|
||||
[0,0, 1,0, 0,1,
|
||||
0,1, 1,0, 1,1]), drawType);
|
||||
gl.enableVertexAttribArray(1);
|
||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coord setup");
|
||||
|
||||
// Now resize these buffers because we want to change what we're drawing.
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
-1,1,0, 1,1,0, -1,-1,0, 1,-1,0,
|
||||
-1,1,0, 1,1,0, -1,-1,0, 1,-1,0]), drawType);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after vertex redefinition");
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
255, 0, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
0, 255, 0, 255,
|
||||
0, 255, 0, 255]), drawType);
|
||||
gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after texture coordinate / color redefinition");
|
||||
|
||||
var numQuads = 2;
|
||||
var indices = new Uint32Array(numQuads * 6);
|
||||
for (var ii = 0; ii < numQuads; ++ii) {
|
||||
var offset = ii * 6;
|
||||
var quad = (ii == (numQuads - 1)) ? 4 : 0;
|
||||
indices[offset + 0] = quad + 0;
|
||||
indices[offset + 1] = quad + 1;
|
||||
indices[offset + 2] = quad + 2;
|
||||
indices[offset + 3] = quad + 2;
|
||||
indices[offset + 4] = quad + 1;
|
||||
indices[offset + 5] = quad + 3;
|
||||
}
|
||||
var indexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices");
|
||||
gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_INT, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
|
||||
}
|
||||
|
||||
function runVerifiesTooManyIndicesTests(drawType) {
|
||||
description("Tests that index validation for drawElements does not examine too many indices");
|
||||
|
||||
var program = wtu.loadStandardProgram(gl);
|
||||
|
||||
gl.useProgram(program);
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.disableVertexAttribArray(1);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
// 4 vertices -> 2 triangles
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0,0, 0,1,0, 1,0,0, 1,1,0 ]), drawType);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
var indexObject = gl.createBuffer();
|
||||
|
||||
debug("Test out of range indices")
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]), drawType);
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
|
||||
var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
|
||||
"gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
}
|
||||
|
||||
function runCrashWithBufferSubDataTests(drawType) {
|
||||
debug('Verifies that the index validation code which is within bufferSubData does not crash.')
|
||||
|
||||
var elementBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 256, drawType);
|
||||
var data = new Uint32Array(127);
|
||||
gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 64, data);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "after attempting to update a buffer outside of the allocated bounds");
|
||||
testPassed("bufferSubData, when buffer object was initialized with null, did not crash");
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,423 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL OES_standard_derivatives Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
<!-- Shaders for testing standard derivatives -->
|
||||
|
||||
<!-- Shader omitting the required #extension pragma -->
|
||||
<script id="missingPragmaFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
float dx = dFdx(texCoord.x);
|
||||
float dy = dFdy(texCoord.y);
|
||||
float w = fwidth(texCoord.x);
|
||||
gl_FragColor = vec4(dx, dy, w, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shader to test macro definition -->
|
||||
<script id="macroFragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
void main() {
|
||||
#ifdef GL_OES_standard_derivatives
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
#else
|
||||
// Error expected
|
||||
#error no GL_OES_standard_derivatives;
|
||||
#endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Shader with required #extension pragma -->
|
||||
<script id="testFragmentShader" type="x-shader/x-fragment">
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
precision mediump float;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
float dx = dFdx(texCoord.x);
|
||||
float dy = dFdy(texCoord.y);
|
||||
float w = fwidth(texCoord.x);
|
||||
gl_FragColor = vec4(dx, dy, w, 1.0);
|
||||
}
|
||||
</script>
|
||||
<!-- Shaders to link with test fragment shaders -->
|
||||
<script id="goodVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
texCoord = vPosition.xy;
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
<!-- Shaders to test output -->
|
||||
<script id="outputVertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
varying vec4 position;
|
||||
void main() {
|
||||
position = vPosition;
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
<script id="outputFragmentShader" type="x-shader/x-fragment">
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
precision mediump float;
|
||||
varying vec4 position;
|
||||
void main() {
|
||||
float dzdx = dFdx(position.z);
|
||||
float dzdy = dFdy(position.z);
|
||||
float fw = fwidth(position.z);
|
||||
gl_FragColor = vec4(abs(dzdx) * 40.0, abs(dzdy) * 40.0, fw * 40.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies the functionality of the OES_standard_derivatives extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
|
||||
// Run all tests once.
|
||||
runAllTests();
|
||||
|
||||
// Run all tests against with a new context to test for any cache issues.
|
||||
debug("");
|
||||
debug("Testing new context to catch cache errors");
|
||||
gl = wtu.create3DContext();
|
||||
ext = null;
|
||||
runAllTests();
|
||||
|
||||
function runAllTests() {
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
// Run tests with extension disabled
|
||||
runHintTestDisabled();
|
||||
runShaderTests(false);
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("OES_standard_derivatives");
|
||||
if (!ext) {
|
||||
testPassed("No OES_standard_derivatives support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled OES_standard_derivatives extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
runHintTestEnabled();
|
||||
runShaderTests(true);
|
||||
runOutputTests();
|
||||
runUniqueObjectTest();
|
||||
|
||||
// Run deferred link tests.
|
||||
runDeferredLinkTests();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("OES_standard_derivatives") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("OES_standard_derivatives listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("OES_standard_derivatives listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("OES_standard_derivatives not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("OES_standard_derivatives not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runHintTestDisabled() {
|
||||
debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension disabled");
|
||||
|
||||
// Use the constant directly as we don't have the extension
|
||||
var FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
|
||||
|
||||
gl.getParameter(FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES should not be queryable if extension is disabled");
|
||||
|
||||
gl.hint(FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "hint should not accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES if extension is disabled");
|
||||
}
|
||||
|
||||
function runHintTestEnabled() {
|
||||
debug("Testing FRAGMENT_SHADER_DERIVATIVE_HINT_OES with extension enabled");
|
||||
|
||||
shouldBe("ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES", "0x8B8B");
|
||||
|
||||
gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "FRAGMENT_SHADER_DERIVATIVE_HINT_OES query should succeed if extension is enabled");
|
||||
|
||||
// Default value is DONT_CARE
|
||||
if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) == gl.DONT_CARE) {
|
||||
testPassed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is DONT_CARE");
|
||||
} else {
|
||||
testFailed("Default value of FRAGMENT_SHADER_DERIVATIVE_HINT_OES is not DONT_CARE");
|
||||
}
|
||||
|
||||
// Ensure that we can set the target
|
||||
gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.DONT_CARE);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "hint should accept FRAGMENT_SHADER_DERIVATIVE_HINT_OES");
|
||||
|
||||
// Test all the hint modes
|
||||
var validModes = ["FASTEST", "NICEST", "DONT_CARE"];
|
||||
var anyFailed = false;
|
||||
for (var n = 0; n < validModes.length; n++) {
|
||||
var mode = validModes[n];
|
||||
gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl[mode]);
|
||||
if (gl.getParameter(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) != gl[mode]) {
|
||||
testFailed("Round-trip of hint()/getParameter() failed on mode " + mode);
|
||||
anyFailed = true;
|
||||
}
|
||||
}
|
||||
if (!anyFailed) {
|
||||
testPassed("Round-trip of hint()/getParameter() with all supported modes");
|
||||
}
|
||||
}
|
||||
|
||||
function runShaderTests(extensionEnabled) {
|
||||
debug("");
|
||||
debug("Testing various shader compiles with extension " + (extensionEnabled ? "enabled" : "disabled"));
|
||||
|
||||
// Expect the macro shader to succeed ONLY if enabled
|
||||
var macroFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "macroFragmentShader");
|
||||
if (extensionEnabled) {
|
||||
if (macroFragmentProgram) {
|
||||
// Expected result
|
||||
testPassed("GL_OES_standard_derivatives defined in shaders when extension is enabled");
|
||||
} else {
|
||||
testFailed("GL_OES_standard_derivatives not defined in shaders when extension is enabled");
|
||||
}
|
||||
} else {
|
||||
if (macroFragmentProgram) {
|
||||
testFailed("GL_OES_standard_derivatives defined in shaders when extension is disabled");
|
||||
} else {
|
||||
testPassed("GL_OES_standard_derivatives not defined in shaders when extension disabled");
|
||||
}
|
||||
}
|
||||
|
||||
// Always expect the shader missing the #pragma to fail (whether enabled or not)
|
||||
var missingPragmaFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "missingPragmaFragmentShader");
|
||||
if (missingPragmaFragmentProgram) {
|
||||
testFailed("Shader built-ins allowed without #extension pragma");
|
||||
} else {
|
||||
testPassed("Shader built-ins disallowed without #extension pragma");
|
||||
}
|
||||
|
||||
// Try to compile a shader using the built-ins that should only succeed if enabled
|
||||
var testFragmentProgram = wtu.loadProgramFromScriptExpectError(gl, "goodVertexShader", "testFragmentShader");
|
||||
if (extensionEnabled) {
|
||||
if (testFragmentProgram) {
|
||||
testPassed("Shader built-ins compiled successfully when extension enabled");
|
||||
} else {
|
||||
testFailed("Shader built-ins failed to compile when extension enabled");
|
||||
}
|
||||
} else {
|
||||
if (testFragmentProgram) {
|
||||
testFailed("Shader built-ins compiled successfully when extension disabled");
|
||||
} else {
|
||||
testPassed("Shader built-ins failed to compile when extension disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runOutputTests() {
|
||||
// This tests does several draws with various values of z.
|
||||
// The output of the fragment shader is:
|
||||
// [dFdx(z), dFdy(z), fwidth(z), 1.0]
|
||||
// The expected math: (note the conversion to uint8)
|
||||
// canvas.width = canvas.height = 50
|
||||
// dFdx = totalChange.x / canvas.width = 0.5 / 50.0 = 0.01
|
||||
// dFdy = totalChange.y / canvas.height = 0.5 / 50.0 = 0.01
|
||||
// fw = abs(dFdx + dFdy) = 0.01 + 0.01 = 0.02
|
||||
// r = floor(dFdx * 40.0 * 255) = 102
|
||||
// g = floor(dFdy * 40.0 * 255) = 102
|
||||
// b = floor(fw * 40.0 * 255) = 204
|
||||
|
||||
var e = 5; // Amount of variance to allow in result pixels - may need to be tweaked higher
|
||||
|
||||
debug("Testing various draws for valid built-in function behavior");
|
||||
|
||||
canvas.width = 50; canvas.height = 50;
|
||||
gl.viewport(0, 0, canvas.width, canvas.height);
|
||||
gl.hint(ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST);
|
||||
|
||||
var positionLoc = 0;
|
||||
var texcoordLoc = 1;
|
||||
var program = wtu.setupProgram(gl, ["outputVertexShader", "outputFragmentShader"], ['vPosition', 'texCoord0'], [0, 1]);
|
||||
var quadParameters = wtu.setupUnitQuad(gl, positionLoc, texcoordLoc);
|
||||
|
||||
function expectResult(target, message) {
|
||||
var locations = [
|
||||
[ 0.1, 0.1 ],
|
||||
[ 0.9, 0.1 ],
|
||||
[ 0.1, 0.9 ],
|
||||
[ 0.9, 0.9 ],
|
||||
[ 0.5, 0.5 ]
|
||||
];
|
||||
for (var n = 0; n < locations.length; n++) {
|
||||
var loc = locations[n];
|
||||
var px = Math.floor(loc[0] * canvas.width);
|
||||
var py = Math.floor(loc[1] * canvas.height);
|
||||
wtu.checkCanvasRect(gl, px, py, 1, 1, target, message, 4);
|
||||
}
|
||||
};
|
||||
|
||||
function setupBuffers(tl, tr, bl, br) {
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, quadParameters[0]);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
1.0, 1.0, tr,
|
||||
-1.0, 1.0, tl,
|
||||
-1.0, -1.0, bl,
|
||||
1.0, 1.0, tr,
|
||||
-1.0, -1.0, bl,
|
||||
1.0, -1.0, br]), gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);
|
||||
};
|
||||
|
||||
// Draw 1: (no variation)
|
||||
setupBuffers(0.0, 0.0, 0.0, 0.0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
expectResult([0, 0, 0, 255],
|
||||
"Draw 1 (no variation) should pass");
|
||||
|
||||
// Draw 2: (variation in x)
|
||||
setupBuffers(1.0, 0.0, 1.0, 0.0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
expectResult([204, 0, 204, 255],
|
||||
"Draw 2 (variation in x) should pass");
|
||||
|
||||
// Draw 3: (variation in y)
|
||||
setupBuffers(1.0, 1.0, 0.0, 0.0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
expectResult([0, 204, 204, 255],
|
||||
"Draw 3 (variation in y) should pass");
|
||||
|
||||
// Draw 4: (variation in x & y)
|
||||
setupBuffers(1.0, 0.5, 0.5, 0.0);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
expectResult([102, 102, 204, 255],
|
||||
"Draw 4 (variation in x & y) should pass");
|
||||
}
|
||||
|
||||
function runUniqueObjectTest()
|
||||
{
|
||||
debug("Testing that getExtension() returns the same object each time");
|
||||
ext = null;
|
||||
gl.getExtension("OES_standard_derivatives").myProperty = 2;
|
||||
webglHarnessCollectGarbage();
|
||||
shouldBe('gl.getExtension("OES_standard_derivatives").myProperty', '2');
|
||||
}
|
||||
|
||||
function runDeferredLinkTests() {
|
||||
debug("");
|
||||
debug("Testing deferred shader compilation tests.");
|
||||
|
||||
// Test for compilation failures that are caused by missing extensions
|
||||
// do not succeed if extensions are enabled during linking. This would
|
||||
// only happen for deferred shader compilations.
|
||||
|
||||
// First test if link succeeds with extension enabled.
|
||||
var glEnabled = wtu.create3DContext();
|
||||
var extEnabled = glEnabled.getExtension("OES_standard_derivatives");
|
||||
if (!extEnabled) {
|
||||
testFailed("Deferred link test expects the extension to be supported");
|
||||
}
|
||||
|
||||
var vertexShader = wtu.loadShaderFromScript(glEnabled, "goodVertexShader");
|
||||
var fragmentShader = wtu.loadShaderFromScript(glEnabled, "macroFragmentShader");
|
||||
|
||||
if (!vertexShader || !fragmentShader) {
|
||||
testFailed("Could not create good shaders.");
|
||||
return;
|
||||
}
|
||||
|
||||
var program = wtu.setupProgram(glEnabled, [vertexShader, fragmentShader]);
|
||||
|
||||
if (!program) {
|
||||
testFailed("Compilation with extension enabled failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new context to test link failure without extension enabled.
|
||||
var glDeferred = wtu.create3DContext();
|
||||
|
||||
var vertexShader = wtu.loadShaderFromScript(glDeferred, "goodVertexShader", glDeferred.VERTEX_SHADER, undefined, undefined, true);
|
||||
var fragmentShader = wtu.loadShaderFromScript(glDeferred, "macroFragmentShader", glDeferred.FRAGMENT_SHADER, undefined, undefined, true);
|
||||
|
||||
if (vertexShader == null || fragmentShader == null) {
|
||||
testFailed("Could not create shaders.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Shader compilations should have failed due to extensions not enabled.
|
||||
glDeferred.getExtension("OES_standard_derivatives");
|
||||
var program = wtu.setupProgram(glDeferred, [vertexShader, fragmentShader]);
|
||||
if (program) {
|
||||
testFailed("Compilation with extension disabled then linking with extension enabled should have failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
testPassed("Compilation with extension disabled then linking with extension enabled.");
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,55 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/oes-texture-float-and-half-float-linear.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
function testPrologue(gl, extensionTypeName) {
|
||||
if (!gl.getExtension(extensionTypeName)) {
|
||||
testPassed("No " + extensionTypeName + " support -- this is legal");
|
||||
return false;
|
||||
}
|
||||
testPassed("Successfully enabled " + extensionTypeName + " extension");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='generateTest("OES_texture_float", "OES_texture_float_linear", "FLOAT", testPrologue)()'>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
function testPrologue(gl) {
|
||||
if (!gl.getExtension("OES_texture_float")) {
|
||||
testPassed("No OES_texture_float support -- this is legal");
|
||||
return false;
|
||||
}
|
||||
|
||||
testPassed("Successfully enabled OES_texture_float extension");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='generateTest("RGBA", "RGBA", "FLOAT", testPrologue, "../../resources/")()'>
|
||||
<canvas id="example" width="32" height="32"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
function testPrologue(gl) {
|
||||
if (!gl.getExtension("OES_texture_float")) {
|
||||
testPassed("No OES_texture_float support -- this is legal");
|
||||
return false;
|
||||
}
|
||||
|
||||
testPassed("Successfully enabled OES_texture_float extension");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='generateTest("RGBA", "RGBA", "FLOAT", testPrologue, "../../resources/")()'>
|
||||
<canvas id="texcanvas" width="2" height="2"></canvas>
|
||||
<canvas id="example" width="2" height="2"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
function testPrologue(gl) {
|
||||
if (!gl.getExtension("OES_texture_float")) {
|
||||
testPassed("No OES_texture_float support -- this is legal");
|
||||
return false;
|
||||
}
|
||||
|
||||
testPassed("Successfully enabled OES_texture_float extension");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='generateTest("RGBA", "RGBA", "FLOAT", testPrologue, "../../resources/")()'>
|
||||
<canvas id="example" width="32" height="32"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,62 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-utils.js"></script>
|
||||
<script src="../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
function testPrologue(gl) {
|
||||
if (!gl.getExtension("OES_texture_float")) {
|
||||
testPassed("No OES_texture_float support -- this is legal");
|
||||
return false;
|
||||
}
|
||||
|
||||
testPassed("Successfully enabled OES_texture_float extension");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload='generateTest("RGBA", "RGBA", "FLOAT", testPrologue, "../../resources/")()'>
|
||||
<canvas id="example" width="32" height="32"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<video width="640" height="228" id="vid" controls>
|
||||
<source src="../../resources/red-green.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
|
||||
<source src="../../resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
|
||||
<source src="../../resources/red-green.theora.ogv" type='video/ogg; codecs="theora, vorbis"' />
|
||||
</video>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue