merged mozilla-central to birch

--HG--
rename : gfx/thebes/GLContextProviderEGL.cpp => gfx/gl/GLContextProviderEGL.cpp
rename : embedding/android/AndroidManifest.xml.in => mobile/android/base/AndroidManifest.xml.in
This commit is contained in:
Brad Lassey 2011-11-21 01:21:42 -05:00
Родитель 9e18690221 764e833c1a
Коммит b219896cab
191 изменённых файлов: 10272 добавлений и 3491 удалений

Просмотреть файл

@ -56,6 +56,7 @@ endif
DIRS += pgo
ifdef ENABLE_TESTS
DIRS += autoconf/test
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
DIRS += mobile/sutagent/android \
mobile/sutagent/android/watcher \

Просмотреть файл

@ -1,4 +1,4 @@
#! /usr/bin/env perl
#!/usr/bin/env perl
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
@ -16,10 +16,12 @@
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1999
# Portions created by the Initial Developer are Copyright (C) 1999-2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Steve Lamm <slamm@netscape.com>
# Joey Armstrong <joey@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
@ -35,29 +37,81 @@
#
# ***** END LICENSE BLOCK *****
# make-makefiles - Quickly create Makefiles for subdirectories.
# Also, creates any needed subdirectories.
#
# usage: make-makefiles [ -t <topsrcdir> -p <print_topsrcdir> -d <depth> ] [ <subdir> | <subdir>/Makefile ] ...
##----------------------------##
##---] CORE/CPAN INCLUDES [---##
##----------------------------##
use strict;
use warnings;
use Getopt::Long;
# Send comments, improvements, bugs to Steve Lamm (slamm@netscape.com).
use Benchmark;
use Cwd;
use File::Basename;
use File::Copy;
use File::Path qw{mkpath};
#$debug = 1;
##-------------------##
##---] EXPORTS [---##
##-------------------##
our $VERSION = qw(2.0);
if ($^O eq 'msys') {
$pwdcmd = 'pwd -W';
##--------------------##
##---] INCLUDES [---##
##--------------------##
##############################################################
# pymake: special case path handling for windows cmd shell.
# if invoked by cmd.exe and msys-perl is in play
# $0 may contain a drive letter
# modules use-or-expect msys/unix paths
# adjust $0 => C:/foo => /c/foo so string tests and
# manipulation can by applied properly.
##############################################################
sub BEGIN
{
if ($^O eq 'msys' && $ENV{PATH} =~ m!\w:/!)
{
$0 =~ s!^(\w):!/$1!;
}
eval 'use FindBin';
die $@ if ($@);
}
else {
$pwdcmd = 'pwd';
use lib $FindBin::Bin;
use makemakefile;
##-------------------##
##---] GLOBALS [---##
##-------------------##
my %argv;
my $t0 = Benchmark->new();
sub END
{
if ($argv{bench})
{
my $t1 = Benchmark->new();
my $delta = timediff($t1, $t0);
print STDERR timestr($delta), "\n";
}
}
##----------------##
##---] MAIN [---##
##----------------##
umask 0;
my $debug = $argv{debug} || 0;
my $pwdcmd = ($^O eq 'msys') ? 'pwd -W' : 'pwd';
# Determine various tree path variables
#
($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
my ($topsrcdir, $ptopsrcdir, $depth, @makefiles) = parse_arguments(@ARGV);
$object_fullpath = `$pwdcmd`;
my $object_fullpath = `$pwdcmd`; # Cwd::getcwd()
chdir $depth;
$object_root = `$pwdcmd`;
my $object_root = `$pwdcmd`; # Cwd::getcwd()
chomp $object_fullpath;
chomp $object_root;
@ -65,24 +119,23 @@ chomp $object_root;
# 'make-makefile' was called. For example, if make-makefile was
# called from "mozilla/gfx/src", then $source_subdir would be
# "gfx/src/".
$source_subdir = "$object_fullpath/";
my $source_subdir = "$object_fullpath/";
my $quoted_object_root = quotemeta($object_root);
$source_subdir =~ s|^$quoted_object_root/||;
# Prefix makefiles with $source_subdir so that paths
# will be relative to the top of the object tree.
#
for $makefile (@makefiles) {
my $makefile;
for $makefile (@makefiles) { # dead code ?
$makefile = "$source_subdir$makefile";
}
create_directories(@makefiles);
# Find the path to the source directory based on how 'make-makefile'
# was invoked. The path is either relative to the object directory
# or an absolute path.
$given_srcdir = find_srcdir($topsrcdir, $depth);
$pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
my $given_srcdir = find_srcdir($topsrcdir, $depth);
my $pgiven_srcdir = find_srcdir($ptopsrcdir, $depth);
if ($debug) {
warn "object_fullpath = $object_fullpath\n";
@ -92,18 +145,21 @@ if ($debug) {
warn "given_srcdir = $given_srcdir\n";
}
@unhandled = update_makefiles($given_srcdir, $pgiven_srcdir, @makefiles);
my @errors;
my @unhandled = update_makefiles_legacy($given_srcdir, $pgiven_srcdir, @makefiles);
push(@errors, $@) if ($@);
run_config_status(@unhandled);
push(@errors, $@) if ($@ && $argv{'no-warnings'});
exit scalar(@errors);
# end of Main
############################################################
sub dirname {
return $_[0] =~ /(.*)\/.*/ ? "$1" : '.';
}
###########################################################################
# find_depth: Pull the value of DEPTH out of a Makefile (or Makefile.in)
###########################################################################
sub find_depth {
my $depth = '';
open(MAKEFILE, "<$_[0]") || die "Unable to open $_[0]: $!\n";
@ -116,39 +172,115 @@ sub find_depth {
return $depth;
}
###########################################################################
## Intent: Parse command line arguments and assign values
###########################################################################
sub parse_arguments {
my @args = @_;
my $depth = '';
my $topsrcdir = '';
my $ptopsrcdir;
my @makefiles = ();
while (1) {
if ($args[0] eq '-d') {
$depth = $args[1];
shift @args;
shift @args;
} elsif ($args[0] eq '-t') {
$topsrcdir = $args[1];
shift @args;
shift @args;
} elsif ($args[0] eq '-p') {
$ptopsrcdir = $args[1];
shift @args;
shift @args;
} else {
last;
}
my @arglist = qw(badtokens! bench
chdir=s
debug
depth|d=s
enhanced
obj=s top|t=s ptop|p=s
src=s dst=s
);
unless(GetOptions(\%argv, @arglist))
{
my $script = join('/', $FindBin::RealBin, $FindBin::Script);
system("perldoc $script </dev/null");
exit
}
@args = @ARGV;
my $topsrcdir = $argv{top} || '';
if (! $topsrcdir)
{
$topsrcdir = $argv{top} = getTopDir();
}
if ($topsrcdir eq '') {
$topsrcdir = $0; # Figure out topsrcdir based on program name.
$topsrcdir =~ s|/?build/autoconf/.*$||;
my $ptopsrcdir ||= $argv{ptop} || $topsrcdir || '';
## Init --no- switch values
foreach my $var (qw(badtokens exclusions warnings))
{
$argv{"no-${var}"} = $argv{$var} || 0;
}
if ($ptopsrcdir eq '') {
$ptopsrcdir = $topsrcdir;
# Propogate parsed arguments for module use [--debug, --verbose]
while (my($k, $v) = each %argv)
{
$main::argv{$k} = $v;
}
if ($depth eq '') {
if ($argv{chdir})
{
chdir $argv{chdir} || die "chdir $argv{chdir} failed: $!";
}
##############################################################
## Arguments allowing make-makefile to be invoked from $topsrc
##############################################################
if (!$argv{top} || !$argv{obj})
{
}
## Limit access to container makefiles for now
elsif ($argv{enhanced})
{
my @errors;
## iterate over @ARGV to preserve original filename for 'unhandled'
my @files = map{ getRelPath($_) } @ARGV;
my $top = getTopDir();
my $obj = getObjDir();
mkdirr(map{ "$obj/$_" } @files);
push(@errors, $@) if ($@); # legacy behavior: do not exit with status
my $exclude = join('/', $FindBin::RealBin, $FindBin::Script);
$exclude .= '.excl'; # $argv{exclude}
my %exclude = getExclusions($exclude);
my @unhandled;
foreach my $relpath (@files)
{
my $rel = join('/', $relpath, 'Makefile.in');
my $mf = join('/', $top, $rel);
next if ($exclude{$rel});
print STDERR " ** relpath=[$relpath], mf=[$mf]\n" if ($main::argv{debug});
my $rc = updateMakefiles($relpath, {depth=>$depth, obj=>$obj, top=>$top});
if ($@)
{
push(@errors, $@);
}
elsif ($rc eq 'badtokens')
{
push(@unhandled, $mf);
}
}
run_config_status(@unhandled);
push(@errors, $@) if ($@ && $argv{'no-warnings'});
exit scalar(@errors);
}
my $depth = $argv{depth} || '';
if (! $depth)
{
foreach my $fyl (@args)
{
if (my $tmp = find_depth($fyl))
{
$depth = $tmp;
last;
}
}
}
if (! $depth) {
# Use $(DEPTH) in the Makefile or Makefile.in to determine the depth
if (-e "Makefile.in") {
$depth = find_depth("Makefile.in");
@ -166,34 +298,21 @@ sub parse_arguments {
# Build the list of makefiles to generate
#
@makefiles = ();
my $makefile;
foreach $makefile (@args) {
$makefile =~ s/\.in$//;
$makefile =~ s/\/$//;
$makefile =~ /Makefile$/
or $makefile =~ /^\.\//
or $makefile .= "/Makefile";
while (@args)
{
next unless my $makefile = shift @args;
$makefile =~ s/\.in$//;
$makefile =~ s/\/$//;
$makefile =~ /Makefile$/
or $makefile =~ /^\.\//
or $makefile .= "/Makefile";
push @makefiles, "$makefile";
}
@makefiles = "Makefile" unless @args;
@makefiles = "Makefile" unless @makefiles;
return ($topsrcdir, $ptopsrcdir, $depth, @makefiles);
}
# Create all the directories at once.
# This can be much faster than calling mkdir() for each one.
sub create_directories {
my @makefiles = @_;
my @dirs = ();
my $ac_file;
foreach $ac_file (@makefiles) {
push @dirs, dirname($ac_file);
}
# Call mkdir with the directories sorted by subdir count (how many /'s)
system "mkdir -p ". join(' ', map("\"$_\"", @dirs)) if @dirs;
}
# Find the top of the source directory
# (Assuming that the executable is in $top_srcdir/build/autoconf)
sub find_srcdir {
@ -214,111 +333,146 @@ sub find_srcdir {
return $ac_given_srcdir;
}
# Output the makefiles.
#
sub update_makefiles {
my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
my @unhandled=();
1;
###########################################################################
## perldoc
###########################################################################
__END__
my $ac_file;
foreach $ac_file (@makefiles) {
my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
my $ac_dir = dirname($ac_file);
my $ac_dots = '';
my $ac_dir_suffix = '';
my $srcdir = '.';
my $top_srcdir = '.';
=head1 NAME
# Determine $srcdir and $top_srcdir
#
if ($ac_dir ne '.') {
$ac_dir_suffix = "/$ac_dir";
$ac_dir_suffix =~ s%^/\./%/%;
$ac_dots = $ac_dir_suffix;
# Remove .. components from the provided dir suffix, and
# also the forward path components they were reversing.
my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
while ($backtracks--) {
$ac_dots =~ s%/[^/]*%%;
}
$ac_dots =~ s%/[^/]*%../%g;
}
if ($ac_given_srcdir eq '.') {
if ($ac_dots ne '') {
$top_srcdir = $ac_dots;
$top_srcdir =~ s%/$%%;
}
} elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
$srcdir = "$pac_given_srcdir$ac_dir_suffix";
$top_srcdir = "$pac_given_srcdir";
} else {
if ($debug) {
print "ac_dots = $ac_dots\n";
print "ac_dir_suffix = $ac_dir_suffix\n";
}
$srcdir = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
$top_srcdir = "$ac_dots$ac_given_srcdir";
}
make-makefile - Generate a Makefile from a F<Makefile.in> template
if ($debug) {
print "ac_dir = $ac_dir\n";
print "ac_file = $ac_file\n";
print "ac_file_in = $ac_file_in\n";
print "srcdir = $srcdir\n";
print "top_srcdir = $top_srcdir\n";
print "cwd = " . `$pwdcmd` . "\n";
}
=head1 SYNOPSIS
# Copy the file and make substitutions.
# @srcdir@ -> value of $srcdir
# @top_srcdir@ -> value of $top_srcdir
#
if (-e $ac_file) {
next if -M _ < -M $ac_file_in; # Next if Makefile is up-to-date.
warn "updating $ac_file\n";
} else {
warn "creating $ac_file\n";
}
make-makefile [--top t] [--obj o] [--depth d] foo/bar/Makefile.in tans/fans/Makefile foo/bar
open INFILE, "<$ac_file_in" or do {
warn "$0: Cannot read $ac_file_in: No such file or directory\n";
next;
};
open OUTFILE, ">$ac_file" or do {
warn "$0: Unable to create $ac_file\n";
next;
};
=head1 DESCRIPTION
while (<INFILE>) {
#if (/\@[_a-zA-Z]*\@.*\@[_a-zA-Z]*\@/) {
# #warn "Two defines on a line:$ac_file:$.:$_";
# push @unhandled, $ac_file;
# last;
#}
Given options and makefile path arguments determine path to the template
F<Makefile.in> beneath a source directory and path to generated F<Makefile>
beneath $MOZ_OBJDIR. DEPTH from destination directory to the 'root' will
also be determined. F<Makefile.in> will be read in, template strings of the
gorm @token@ will be replaced with derived values and a generated makefile
will be written out as F<Makefile>.
s/\@srcdir\@/$srcdir/g;
s/\@top_srcdir\@/$top_srcdir/g;
Makefile DEPTH= can be determined in a few different ways:
o The string C<DEPTH=../../..> may be embedded within F<Makefile.in>.
o Search parent directories for F<Makefile.in> and use it to assign the child.
if (/\@[_a-zA-Z]*\@/) {
#warn "Unknown variable:$ac_file:$.:$_";
push @unhandled, $ac_file;
last;
}
print OUTFILE;
}
close INFILE;
close OUTFILE;
}
return @unhandled;
}
sub run_config_status {
my @unhandled = @_;
=head2 Option List
# Run config.status with any unhandled files.
#
if (@unhandled) {
$ENV{CONFIG_FILES}= join ' ', @unhandled;
system "./config.status";
}
}
=over 4
=item --chdir
Move to this directory before doing anything else
=item -d, --depth
Explicitly specify the relative path from directory containing Makefile.in
to the top sandbox directory. memory/makefile, DEPTH=../.., js/src/config, DEPTH=..
=item --enhanced
Use alternate/simplified path construction when options --top and --obj are
passed. This feature will be used by container makefiles to support makefile
generation while cd'd into the sandbox top directory.
=item -t, --top
Path the root of a development sandbox.
=item --obj
Path to object directory where generated makefile will be written ($MOZ_OBJDIR).
=item --ptop
Print top source dir
=back
=head2 Options List DEBUG
=over 4
=item --bench
Enable script benchmarking, report elapsed runtime.
=item --debug
Enable script debug mode.
=back
=head2 Options List --NO-
=over 4
=item --no-badtokens (wip)
Handle unexpanded @token@ makefile tokens as an error condition.
Do not rely on system(config.status) to externally supply values.
=item --no-excludes
Ignore file entries on the exclusion list, generate everything.
=item --no-warnings
Warnings are handled as an error condition.
=back
=head2 Examples
=over 4
=item * make-makefile -t /mozilla/nightly -d . memory/mozalloc
cd $MOZ_OBJDIR;
--top and --depth are explicitly set for generting memory/mozalloc/Makefile.
=item * make-makefile -t /mozilla/nightly -d ../../../.. html5lib_tree_construction/Makefile
cd $MOZ_OBJDIR/parser/htmlparser/tests/mochitest
--top and --depth are explicitly set for generting a makefile from within
a subdirectory of $MOZ_OBJDIR
=item * make-makefile --top /mozilla/nightly --obj /mozilla/nightly/obj memory/mozalloc
With --top and --obj explicitly set generate $MOZ_OBJDIR/memory/mozalloc/Makefile
while sitting in the sandbox root.
=back
=head2 Work In Progress
=over 4
=item --no-badtokens
Fail on unexpanded @foo@ makefile tokens. Any tokens that can be expanded
directly by make-makefile will avoid config.status shell overhead.
=item Depth from delta(--obj, --top)
If DEPTH= has not been embedded within a makefile the value could
be set directly if --top and --obj are specified and the paths overlap.
=back
=head1 SEE ALSO
L<config/rules.mk>
=cut

Просмотреть файл

@ -0,0 +1,5 @@
###########################################################################
## Intent: Exclusion list for container make builds
###########################################################################
# EOF

Просмотреть файл

@ -0,0 +1,745 @@
package makemakefile;
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (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.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1999-2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Steve Lamm <slamm@netscape.com>
# Joey Armstrong <joey@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
##----------------------------##
##---] CORE/CPAN INCLUDES [---##
##----------------------------##
use strict;
use warnings;
# use feature 'state'; 5.10+ not available everywhere
##-------------------##
##---] EXPORTS [---##
##-------------------##
our $VERSION = qw(2.0);
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(dirname_legacy
getConfig getDepth getRelPath getObjDir getTopDir mkdirr
getExclusions
run_config_status
updateMakefiles
update_makefiles_legacy
);
##--------------------##
##---] INCLUDES [---##
##--------------------##
use Cwd;
use Cwd qw{abs_path};
use FindBin;
use File::Basename;
use File::Copy;
##-------------------##
##---] GLOBALS [---##
##-------------------##
umask 0;
my $cwd = Cwd::abs_path('.');
my %argv;
###########################################################################
## Intent: Helper function, retrieve contents of a file with error checking
## -----------------------------------------------------------------------
## Args:
## scalar path to input file
## Returns:
## array contents of the given file
## $@ set on error
###########################################################################
sub cat
{
my $fyl = shift || '';
$@ = '';
my @data;
local *FYL;
if (!open(FYL, $fyl))
{
$@ = "open($fyl) failed: $!";
}
else
{
@data = <FYL>;
close(FYL);
}
return @data;
} # cat
###########################################################################
## Intent: Return directory path for a given argument
## -----------------------------------------------------------------------
## -----------------------------------------------------------------------
## Todo:
## o Check if function can be replaced by File::Basename::dirname()
###########################################################################
sub dirname_legacy
{
my $str = (@_ && defined($_[0])) ? shift : '';
return $str =~ /(.*)\/.*/ ? "$1" : '.';
}
###########################################################################
## Intent: Given a list of makefile paths recursively create all
## directories between file and the root
## -----------------------------------------------------------------------
## Args:
## array A list of makefiles
## fargs Function arguments
## mode Filesystem mode used for directory creation
## Returns:
## $@ Set on error
## 0 on success
## -----------------------------------------------------------------------
## Note:
## Reporting directory creation can be enabled by the --verbose
## command line argument.
###########################################################################
sub mkdirr
{
my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
my $mode = $fargs{mode} || 0755;
my $verbose = $main::argv{verbose} || 0;
$@ = '' unless ($fargs{recursive});
$fargs{recursive} = 1;
my @errors;
push(@errors, $@) if ($@);
foreach my $path (@_)
{
(my $dir = $path) =~ s%/?Makefile[^/]*$%%o;
next unless (length($dir));
next if (-e $dir);
mkdirr( dirname($dir), \%fargs);
eval{ File::Path::mkpath($dir, $verbose, 0755); };
push(@errors, $@) if ($@);
}
$@ = join("\n", @errors);
return $@ ? 0 : 1;
} # mkdirr
###########################################################################
## Intent: Read in configure values and return a hash of key/value pairs
## -----------------------------------------------------------------------
## Args:
## fargs Function arguments
## reset clear value storage and repopulate
## Returns:
## hash configure data to use for makefile substitutions
## -----------------------------------------------------------------------
## Todo: wrapper for reading config* and run_config_status
###########################################################################
my %_CONFIG_; # todo: state %config; w/5.10
sub getConfig
{
my %fargs = (@_ && ref($_[$#_]) eq 'HASH') ? %{ (pop) } : ();
if ($fargs{reset})
{
%_CONFIG_ = ();
shift;
}
#my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
#my $ac_dir = dirname_legacy($ac_file);
#my $ac_dots = '';
#my $ac_dir_suffix = '';
#my $srcdir = '.';
#my $top_srcdir = '.';
unless (%_CONFIG_)
{
while (@_)
{
my ($k, $v) = splice(@_, 0, 2);
$_CONFIG_{$k} = $v;
}
}
return %_CONFIG_;
} # getConfig
###########################################################################
## Intent: Determine path depth between leaf and root directory.
## o DEPTH= may be set by makefile content
## o DEPTH= may be set by Makefile in a parent
## o Manually determine by relpath form leaf to sandbox top
## -----------------------------------------------------------------------
## Args:
## scalar Path to makefile or directory to determine DEPTH for
## Returns:
## scalar Relative path from leaf to root directory
## -----------------------------------------------------------------------
###########################################################################
sub getDepth($)
{
my $fyl = shift || '';
my @path = split(m%/%o, $fyl);
pop(@path) if ('Makefile' eq substr($path[$#path], 0, 8));
my $depth;
my @depth;
my $top = getTopDir();
my @top = split(m%/%o, $top);
my @pathNoTop = @path;
splice(@pathNoTop, 0, scalar(@top));
SEARCH:
while (@path)
{
## Search for a file containing DEPTH=../..
foreach my $fyl ( qw{Makefile.in Makefile} )
{
my $path = join('/', @path, $fyl);
local *FYL;
if (!open(FYL, $path)) {} # NOP
elsif (my @tmp = map{ /^\s*DEPTH\s*=\s*([\.\/]+)/o ? $1 : () } <FYL>)
{
$depth = join('/', @depth, shift @tmp);
last SEARCH;
}
close(FYL);
}
pop @path;
pop @pathNoTop;
if (0 == scalar(@pathNoTop))
{
$depth = join('/', @depth);
last;
}
## Construct path manually
push(@depth, '..');
}
return $depth;
} # getDepth
###########################################################################
## Intent: Read in the exclusion file
###########################################################################
sub getExclusions
{
my $file = shift || '';
return () if ($main::argv{'no-exclusions'});
my %exclude;
if ($file)
{
my @data = cat($file);
foreach (@data)
{
next unless ($_);
next if (/^\s*\#/o);
next unless (m%/%);
chomp;
$exclude{$_}++;
}
}
return %exclude;
} # getExclusions
###########################################################################
## Intent: Given the path to a makefile beneath either src or obj
## derive the relative path prefix between makefile and root.
###########################################################################
sub getRelPath
{
my $path0 = shift;
my $abspath;
# Determine type and orientation
my $name = basename($path0);
my $haveMF = ($name eq 'Makefile.in') ? 1
: ($name eq 'Makefile') ? -1
: 0
;
####################################################
## Prep work: form a relative path with ../ removed
####################################################
my $top = getTopDir();
my $obj = getObjDir();
## If the same Makefile will be created alongside Makefile.in
my $topQM = quotemeta($top);
my $objQM = quotemeta($obj);
if ('..' eq substr($path0, 0, 2))
{
my @cwd = split(m%/%, $cwd);
my @pth = split(m%/%, $path0);
while (@pth && $pth[0] eq '..')
{
pop(@cwd);
shift @pth;
}
$path0 = join('/', @cwd, @pth);
$abspath = $path0;
}
if ('/' eq substr($path0, 0, 1))
{
$path0 =~ s%^$objQM\/?%%;
$path0 =~ s%^$topQM\/?%%;
}
#######################################################################
## Build a list of directories to search. Input source will be one
## of path to Makefile.in, path to Makefile, directory, file within
## a directory or relative path from cwd.
#######################################################################
my @subdirs;
my $path = (0 == $haveMF) ? $path0 : dirname($path0);
push(@subdirs, $path); # containing directory
push(@subdirs, dirname($path)) if (0 == $haveMF && -f $path); # Arg is file within a directory
push(@subdirs, $cwd); # relative to pwd
# obj - path to generated makefile
# top - path to Makefile.in source template
my @prefixes = ('/' ne substr($path0, 0, 1))
? (&getTopDir, &getObjDir)
: ()
;
ON_SAFARI:
for my $prefix (@prefixes)
{
next unless ($prefix); # no command line not passed
foreach my $subdir (@subdirs)
{
foreach my $mf ('Makefile.in', 'Makefile')
{
my $path = join('/', $prefix, $subdir, $mf);
if (-e $path)
{
$name = $mf;
$haveMF = ($mf eq 'Makefile.in') ? 1 : -1;
$abspath = $path;
last ON_SAFARI;
}
}
}
}
#######################################################################
## Generated makefile does not yet exist or path is invalid.
## Should this conditon be handled to detect non-existent Makefile.in:
## Makefile.am => Makefile.in => Makefile but Makefile.in
#######################################################################
if (!$abspath && -1 == $haveMF && $obj)
{
$abspath = ('/' eq substr($path0, 0, 1))
? $path0
: join('/', $obj, $path0)
;
}
########################################################
## If --top and/or --obj specified extract relative path
########################################################
my $relpath;
if (! $abspath)
{
# Error, fall through
}
elsif (1 == $haveMF) # Makefile.in
{
## err w/o --top
(my $tmp = $abspath) =~ s%^$topQM/?%%;
$relpath = dirname($tmp) unless ($tmp eq $abspath);
}
elsif (-1 == $haveMF) # Makefile
{
## err w/o --obj
(my $tmp = $abspath) =~ s%^$objQM/?%%;
$relpath = dirname($tmp) unless ($tmp eq $abspath);
}
$relpath ||= '';
$relpath =~ s%/./%/%og; # filter ./
$@ = ($relpath) ? '' : "ERROR($path0): Unable to locate sources";
return $relpath || '';
} # getRelPath
###########################################################################
## Intent: Determine sandbox root from script startup directory
## -----------------------------------------------------------------------
## Args:
## _set_ optional, if passed use the given value as path
## _reset_ clear cached directory path to reassign
## Returns:
## scalar - absolute path to the sandbox root directory
## -----------------------------------------------------------------------
###########################################################################
my $gtd_dir;
sub getTopDir
{
if (@_) # testing override
{
$gtd_dir = abs_path($_[1] || '.') if ($_[0] eq '_set_');
$gtd_dir = '' if ($_[0] eq '_reset_');
}
unless ($gtd_dir)
{
## Set by command line
if ($main::argv{top})
{
$gtd_dir = $main::argv{top};
}
else
{
my $path = abs_path($FindBin::RealBin);
my @path = split(m%/%o, $path);
## --2 memory/mozalloc/Makefile.in
## --3 was this for FindBin::Script ?
splice(@path, -2);
$gtd_dir = join('/', @path);
}
}
return $gtd_dir;
} # getTopDir
###########################################################################
## Intent: Determine path to MOZ_OBJDIR/object directory
## -----------------------------------------------------------------------
## Args:
## _set_ optional testing arg, if passed re-compute cached value
## Returns:
## scalar - absolute path to the sandbox object directory
## -----------------------------------------------------------------------
###########################################################################
my $god_dir;
sub getObjDir
{
if (@_) # testing override
{
if ($_[0] eq '_reset_')
{
$god_dir = '';
shift;
}
elsif ($_[0] eq '_set_')
{
shift;
my $path = $_[0] || '.';
$god_dir = abs_path($path);
shift;
}
}
## extract $obj from given path
unless ($god_dir)
{
if ($main::argv{obj})
{
$god_dir = $main::argv{obj};
}
elsif (@_ && 'Makefile' eq substr($_, -8))
{
$god_dir = abs_path(shift);
}
else # assume we are sitting in moz_objdir
{
$god_dir = abs_path('.');
}
}
return $god_dir;
} # getObjDir
###########################################################################
## Intent: Generate Makefile from a given Makefile.in template
## -----------------------------------------------------------------------
## Args:
## scalar Relative path to a directory containing a makefile
## fargs Hash ref of function arguments.
## obj Absolute path to MOZ_OBJ/a destination directory
## top Absolute path to the sandbox root
## Returns:
## $@ Set on error
## scalar
## 1 True if the makefile was updated
## 0 Otherwise
## badtokens - If the makefile contains unexpandable @token@ strings
## -----------------------------------------------------------------------
###########################################################################
sub updateMakefiles
{
my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
local $_;
$@ = '';
my $top = $fargs{top};
my $obj = $fargs{obj};
my $relpath = shift || '';
my $src = join('/', $top, $relpath, 'Makefile.in');
my $depth = getDepth($src);
my @src = cat($src);
return 0 if ($@);
my $dst = join('/', $obj, $relpath, 'Makefile');
my @dst = cat($dst);
$@ = '';
my $dstD = dirname($dst);
mkdirr($dstD);
return 0 if ($@);
my %data =
( getConfig(),
depth => $depth,
srcdir => join('/', $top, $relpath),
top_srcdir => $top,
);
my $line = 0;
my @data;
while (scalar @src)
{
$line++;
$_ = shift(@src);
## Expand embedded @foo@
while (/\@[^\@\s\$]+\@/go)
{
my $end = pos($_);
my $val = $&;
my $len = length($val);
$val =~ s/^\@\s*//o;
$val =~ s/\s*\@$//o;
## Identify expansions to see if we can avoid shell overhead
if (!defined $data{$val} && !$argv{'no-badtokens'})
{
if (1) # warnings
{
print STDERR "WARNING: token $val not defined\n";
print STDERR " line $line, src: $src\n";
}
return 'badtokens';
}
# Insert $(error txt) makefile macros for invalid tokens
my $val1 = defined($data{$val})
? $data{$val}
: "\$(error $FindBin::Script: variable ${val} is undefined)"
;
substr($_, ($end-$len), $len, $val1);
}
push(@data, $_);
}
if (("@data" eq "@dst") && scalar(@data))
{
print "Skipping up2date makefile: $dst\n" if ($argv{verbose});
}
else
{
my $action = (scalar @dst) ? 'Updating' : 'Creating';
print "$action makefile: $dst\n";
my $tmp = join('.', $dst, "tmp_$$");
if (!open(FYL, "> $tmp"))
{
$@ = "open($tmp) failed: $!";
}
else
{
print FYL @data;
close(FYL);
## Install the new makefile
File::Copy::move($tmp, $dst)
|| ($@ = "move($tmp, $dst) failed: $!");
}
}
return $@ ? 0 : 1;
} # updateMakefiles
# Output the makefiles.
#
sub update_makefiles_legacy {
my ($ac_given_srcdir, $pac_given_srcdir, @makefiles) = @_;
my $debug = $main::argv{debug} || 0;
my $pwdcmd = ($^O eq 'msys') ? 'pwd -W' : 'pwd';
my @unhandled=();
my @warn;
my $ac_file;
foreach $ac_file (@makefiles) {
my $ac_file_in = "$ac_given_srcdir/${ac_file}.in";
my $ac_dir = dirname_legacy($ac_file);
my $ac_dots = '';
my $ac_dir_suffix = '';
my $srcdir = '.';
my $top_srcdir = '.';
# Determine $srcdir and $top_srcdir
#
if ($ac_dir ne '.') {
$ac_dir_suffix = "/$ac_dir";
$ac_dir_suffix =~ s%^/\./%/%;
$ac_dots = $ac_dir_suffix;
# Remove .. components from the provided dir suffix, and
# also the forward path components they were reversing.
my $backtracks = $ac_dots =~ s%\.\.(/|$)%%g;
while ($backtracks--) {
$ac_dots =~ s%/[^/]*%%;
}
$ac_dots =~ s%/[^/]*%../%g;
}
if ($ac_given_srcdir eq '.') {
if ($ac_dots ne '') {
$top_srcdir = $ac_dots;
$top_srcdir =~ s%/$%%;
}
} elsif ($pac_given_srcdir =~ m%^/% or $pac_given_srcdir =~ m%^.:/%) {
$srcdir = "$pac_given_srcdir$ac_dir_suffix";
$top_srcdir = "$pac_given_srcdir";
} else {
if ($debug) {
print "ac_dots = $ac_dots\n";
print "ac_dir_suffix = $ac_dir_suffix\n";
}
$srcdir = "$ac_dots$ac_given_srcdir$ac_dir_suffix";
$top_srcdir = "$ac_dots$ac_given_srcdir";
}
if ($debug) {
print "ac_dir = $ac_dir\n";
print "ac_file = $ac_file\n";
print "ac_file_in = $ac_file_in\n";
print "srcdir = $srcdir\n";
print "top_srcdir = $top_srcdir\n";
print "cwd = " . `$pwdcmd` . "\n";
}
# Copy the file and make substitutions.
# @srcdir@ -> value of $srcdir
# @top_srcdir@ -> value of $top_srcdir
#
if (-e $ac_file) {
next if -M _ < -M $ac_file_in; # Next if Makefile is up-to-date.
warn "updating $ac_file\n";
} else {
warn "creating $ac_file\n";
}
mkdirr(dirname($ac_file));
open INFILE, "<$ac_file_in" or do {
warn "$0: Cannot read $ac_file_in: No such file or directory\n";
next;
};
open OUTFILE, ">$ac_file" or do {
warn "$0: Unable to create $ac_file\n";
next;
};
while (<INFILE>) {
s/\@srcdir\@/$srcdir/g;
s/\@top_srcdir\@/$top_srcdir/g;
if (/\@[_a-zA-Z]*\@/) {
#warn "Unknown variable:$ac_file:$.:$_";
push @unhandled, $ac_file;
last;
}
print OUTFILE;
}
close INFILE;
close OUTFILE;
}
return @unhandled;
} # update_makefiles_legacy
###########################################################################
## Intent: Invoke config.status for unknown makefiles to create
## directory hierarchy for the tree.
## -----------------------------------------------------------------------
## Args:
## array an optional list of makefiles to process
## Returns:
## 0 on success
## $# set on error
## -----------------------------------------------------------------------
## Note: Is this function needed anymore ? Undefined tokens should fail
## at time of expansion rather than having to source config.status.
## Also config.status could be parsed to define values and avoide the
## shell overhead altogether.
###########################################################################
sub run_config_status {
my @unhandled = @_;
# Run config.status with any unhandled files.
#
my @errors;
if (@unhandled) {
local $ENV{CONFIG_FILES}= join ' ', @unhandled;
my $conf = 'config.status';
if (! -e $conf) # legacy behavior, warn rather than err
{
my $cwd = cwd();
my $err = "$FindBin::Script ERROR: Config file $conf does not exist, cwd=$cwd";
push(@errors, $err);
}
elsif (0 != system("./config.status"))
{
my $cwd = cwd();
push(@errors, "config.status failed \$?=$?, \$!=$!, cwd: $cwd");
}
}
$@ = join("\n", @errors);
## Legacy behavior: config.status problems are not fatal {yet}.
## Display warning since caller will not be calling die.
warn $@ if ($@ && $argv{'no-warnings'});
return $@ ? 1 : 0;
}
1;

Просмотреть файл

@ -0,0 +1,94 @@
# -*- makefile -*-
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (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.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Joey Armstrong <joey@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
##################################################
## Gather a list of tests, generate timestamp deps
##################################################
TS=.ts
ifneq (,$(findstring check,$(MAKECMDGOALS)))
allsrc = $(wildcard $(srcdir)/*)
tests2run = $(notdir $(filter %.tpl,$(allsrc)))
tests2run += $(notdir $(filter %.tpm,$(allsrc)))
check_targets += $(addprefix $(TS)/,$(tests2run))
endif
all_nop: # export, libs and tools are not needed
check:: $(TS) $(check_targets)
#############################################
# Only invoke tests when sources have changed
#############################################
$(TS)/%: $(srcdir)/%
$(PERL) $(srcdir)/runtest $<
@touch $@
parent = $(patsubst %/,%,$(dir $(srcdir)))
$(TS)/make-makefile.tpl: \
$(srcdir)/make-makefile.tpl\
$(parent)/makemakefile.pm\
$(NULL)
$(PERL) $(srcdir)/runtest $<
@touch $@
$(TS)/makemakefile.tpm: \
$(srcdir)/makemakefile.tpm \
$(parent)/makemakefile.pm \
$(NULL)
$(PERL) $(srcdir)/runtest $<
@touch $@
#####################################################
## Extra dep needed to synchronize parallel execution
#####################################################
$(TS): $(TS)/.done
$(TS)/.done:
$(MKDIR) -p $(dir $@)
touch $@
GARBAGE_DIRS += $(TS)
# EOF

Просмотреть файл

@ -0,0 +1,4 @@
jsautocfg.h: jscpucfg$(HOST_BIN_SUFFIX)
@$(RM) $@ jsautocfg.tmp
./jscpucfg > jsautocfg.tmp
mv jsautocfg.tmp $@

Просмотреть файл

@ -0,0 +1,4 @@
jsautocfg.h: jscpucfg$(HOST_BIN_SUFFIX)
@$(RM) $@ jsautocfg.tmp
./jscpucfg > jsautocfg.tmp
mv jsautocfg.tmp $@

Просмотреть файл

@ -0,0 +1,8 @@
###########################################################################
## Intent: Exclusion list for container make builds
###########################################################################
/dev/null
/foo/bar
/a/b/c
/a/b/d

Просмотреть файл

@ -0,0 +1,436 @@
#!/usr/bin/env perl
###########################################################################
## Intent: Unit test to verify make-makefile.tpl
###########################################################################
##----------------------------##
##---] CORE/CPAN INCLUDES [---##
##----------------------------##
use strict;
use warnings;
#use feature 'state'; # 5.10+ not installed everywhere
use Getopt::Long;
use Cwd;
use Cwd qw{abs_path};
use File::Basename;
use File::Copy;
use File::Path;
use File::Temp qw{ tempdir };
use Test;
sub BEGIN { plan tests => 4 };
my @workdirs;
sub END { system("/bin/rm -fr @workdirs"); } # cleanup behind interrupts
##-------------------##
##---] EXPORTS [---##
##-------------------##
use FindBin;
our $VERSION = qw(1.0);
##------------------##
##---] INCLUDES [---##
##------------------##
use FindBin;
use lib "$FindBin::RealBin/..";
use makemakefile;
##-------------------##
##---] GLOBALS [---##
##-------------------##
my %argv;
###########################################################################
## Intent: Create a temp sandbox populated with sources
## -----------------------------------------------------------------------
## Args:
## array a list of file paths to copy
## Returns:
## $@ set on error
## scalar path to scratch sandbox
## -----------------------------------------------------------------------
###########################################################################
my $root; # state $root not available
sub createSandbox
{
my @errors;
unless ($root)
{
my @tmp = split(m%/%, $FindBin::RealBin);
splice(@tmp, -3);
$root = join('/', @tmp);
}
my $work = tempdir();
push(@workdirs, $work);
my @dirs = map{ join('/', $work, dirname($_)) } @_;
mkdirr(@dirs);
push(@errors, "createSandbox: $@") if ($@);
foreach (@_)
{
## Copy sources into the temp source directory
my $src = join('/', $root, $_);
my $dst = join('/', $work, $_);
unless (copy($src, $dst))
{
push(@errors, "copy($src, $dst) failed: $!");
}
}
print STDERR "createSandbox: $work\n" if ($main::argv{debug});
$@ = join('', map{ "$_\n" } @errors);
$work;
} # createSandbox
###########################################################################
## Intent: wrapper to run the make-makefile command.
## -----------------------------------------------------------------------
## Args:
## array command line arguments passed to make-makefile
## Returns:
## array command output
## $@ set by shell exit status, empty string on success
## $? command shell exit status
###########################################################################
my $mm; # state $mm not available
sub makemakefile
{
my %fargs = (@_ && ref($_[$#_])) ? %{ (pop) } : ();
$mm ||= join('/', dirname($FindBin::Bin), 'make-makefile'); # cmd in parent of test/
my $cmd = join(' ', $mm, @_);
print "RUNNING: $cmd\n" if ($fargs{debug});
my @out = `$cmd 2>&1`;
print STDERR map{ "out> $_" } @out if ($argv{verbose});
$@ = (0 == $?) ? '' : "Command failed: $cmd\n@out";
@out;
} # makemakefile
###########################################################################
## Intent: Helper function, display the contents of a given sandbox
## -----------------------------------------------------------------------
## Args:
## scalar Path to sandbox
## Returns:
## none
## -----------------------------------------------------------------------
###########################################################################
sub find_ls
{
my $path = shift || '';
# Assuming dot contributes to cryptic problems
die "find_ls: a path is required" unless ($path);
my $cmd = "find $path -ls";
print "\nRunning: $cmd\n";
print '=' x 75, "\n";
print `$cmd`;
} # myls
###########################################################################
## Intent: Verify make-makefile is able to digest paths and generate
## makefiles when object directory is a child of top.
###########################################################################
sub check_makemakefile
{
my $work = createSandbox
(
'memory/mozalloc/Makefile.in',
'toolkit/system/windowsproxy/Makefile.in',
'toolkit/crashreporter/google-breakpad/src/client/Makefile.in',
);
my $workdir = createSandbox();
my $top = $workdir;
chdir $top;
my $objA = 'obj-arch-dir';
my $obj = join('/', $top, $objA);
# getTopDir()
local $main::argv{top} = $work;
local $main::argv{obj} = $obj;
getObjDir('_reset_');
my @root = split(m%/%, $FindBin::RealBin);
splice(@root, -3);
my $root = join('/', @root);
my @args =
(
[
banner => "--top and --obj are impled, generate Makefile",
rel => 'memory/mozalloc',
cmd => join(' ',
'--top', $top,
'--obj', $obj,
'memory/mozalloc/Makefile',
),
],
[
banner => "--top and abs(obj) passed",
rel => "toolkit/system/windowsproxy",
cmd => join(' ',
'--top', $top,
"$obj/toolkit/system/windowsproxy/Makefile",
),
exp => "$obj/toolkit/system/windowsproxy/Makefile",
skip => 1, #
],
[
banner => "--obj and abs(top) passed",
rel => "toolkit/crashreporter/google-breakpad/src/client",
cmd => join(' ',
'--obj', $obj,
"$top/toolkit/crashreporter/google-breakpad/src/client/Makefile.in",
),
exp => "$top/toolkit/crashreporter/google-breakpad/src/client/Makefile.in",
skip => 1, #
],
);
foreach (@args)
{
my %rec = @{ $_ };
next if ($rec{skip});
next unless ($rec{rel});
my $srcR = join('/', $top, $rec{rel});
my $dstR = join('/', $obj, $rec{rel});
my $src = join('/', $top, $rec{rel}, 'Makefile.in');
my $dst = join('/', $obj, $rec{rel}, 'Makefile');
# Use distinct sources to avoid cleanup overhead between tests
die "Test source already used: $dstR" if (-d $dstR);
## Copy sources into the temp source directory
my $rootR = join('/', $root, $rec{rel});
my $rootS = join('/', $root, $rec{rel}, 'Makefile.in');
File::Path::mkpath($srcR, 0, 0700);
copy($rootS, $src) or die "copy($rootS, $src) failed: $!";
die "source does not exist: $src" unless (-e $src);
######################
## Generate and verify
######################
print STDERR "RUNNING: $rec{banner}\n" if ($argv{debug});
my @errs;
makemakefile('--enhanced', $rec{cmd}, {verbose=>1});
if ($@)
{
push(@errs, "\$@ should not be set: $@\n");
}
elsif (! -e $dst)
{
push(@errs, "Generated makefile does not exist: $dst, banner: $rec{banner}\n");
}
ok(scalar(@errs), 0, "Errors detected:\n" . join(" $_", @errs));
find_ls($top) if (@errs);
}
} # check_makemakefile
###########################################################################
## Intent: Verify make-makefile is able to digest paths and generate
## makefiles when top/MOZ_OBJDIR are not parent/child directories
## ---------------------------------------------------------------------------
## Args:
## none
## Returns:
## none
## ---------------------------------------------------------------------------
###########################################################################
sub check_makemakefile_distinct
{
my $workdir = createSandbox();
# my $workdir = tempdir();
###############################################
## Now update when top/obj are not parent/child
###############################################
my $top = join('/', $workdir, 'top');
my $obj = join('/', $workdir, 'obj');
$main::argv{top} = $top;
$main::argv{obj} = $obj; # test afterward, using undef ?
my @sbxroot = split(m%/%, $FindBin::RealBin);
splice(@sbxroot, -2);
my $sbxroot = join('/', @sbxroot);
## Copy in a makefile template to to convert
File::Path::mkpath(["$top/memory/mozalloc"], 0, 0700);
copy("$sbxroot/memory/mozalloc/Makefile.in", "$top/memory/mozalloc/Makefile.in");
# work/memory/mozalloc/Makefile.in
my @args =
(
[
banner => '--top and --obj are distinct [1]',
cmd => "--obj $obj memory/mozalloc/Makefile",
exp => "$obj/memory/mozalloc/Makefile",
],
[
banner => "--top and --obj are distinct [2]",
cmd => "--top $top memory/mozalloc/Makefile.in",
exp => "$obj/memory/mozalloc/Makefile",
skip => 1, # test problem: top != obj
],
[
banner => "--top and --obj are distinct [3]",
cmd => join(' ',
"--top $top",
"--obj $obj",
"memory/mozalloc/Makefile.in",
),
exp => "$obj/memory/mozalloc/Makefile",
skip => 1, # test problem: top != obj
],
);
foreach (@args)
{
my %rec = @{ $_ };
print STDERR "banner: $rec{banner}\n" if ($argv{debug});
next if $rec{skip};
unlink $rec{exp};
makemakefile('--enhanced', $rec{cmd});
my @errs;
if ($@)
{
push(@errs, "\$@ should not be set: $@\n");
}
elsif (! -e $rec{exp})
{
push(@errs, "Makefile does not exist: $rec{exp}\n");
}
ok(scalar(@errs), 0, "Errors detected:\n" . join(" $_", @errs));
}
} # check_makemakefile_distinct
###########################################################################
## Intent: Verify legacy behavior, invoke make-makefile when cwd is
## a subdirectory beneath MOZ_OBJDIR.
## -----------------------------------------------------------------------
## Args:
## none
## Returns:
## none
## -----------------------------------------------------------------------
###########################################################################
sub check_makemakefile_legacy
{
my $work = createSandbox
(
'memory/mozalloc/Makefile.in',
'parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile.in',
);
my $obj = join('/', $work, 'obj');
mkdir $obj;
my @args =
(
{
banner => '-t path -d dot',
cwd => $obj,
cmd => "-t $work -d . memory/mozalloc/Makefile",
exp => "$obj/memory/mozalloc/Makefile",
skip => 0,
},
{
banner => '-t path -d relpath',
cwd => join('/', $obj, 'parser/htmlparser/tests/mochitest'),
cmd => "-t $work -d ../../../.. html5lib_tree_construction/Makefile",
exp => "$obj/parser/htmlparser/tests/mochitest/html5lib_tree_construction/Makefile",
skip => 0,
},
);
foreach (@args)
{
my %rec = %{ $_ };
next if ($rec{skip});
## make-make while sitting in $objdir
mkdirr($rec{cwd});
chdir $rec{cwd} || die "chdir $rec{cwd} failed; $!";
makemakefile($rec{cmd});
my @errs;
if ($@)
{
push(@errs, "make-makefile $rec{cmd} failed: $@");
}
elsif (! -e $rec{exp})
{
push(@errs, "generated makefile does not exist: $rec{exp}");
}
ok(scalar(@errs), 0, "Errors detected: @errs");
find_ls($work) if (@errs);
}
chdir $FindBin::RealBin;
} # check_makemakefile_legacy
###########################################################################
## Intent: Smoke tests for the unittests module
###########################################################################
sub smoke
{
print STDERR "Running test: smoke()\n" if ($argv{debug});
} # smoke()
###########################################################################
## Intent: Intitialize global test objects and consts
###########################################################################
sub init
{
print "Running: init()\n" if ($argv{debug});
# testplan(24, 0);
} # init()
##----------------##
##---] MAIN [---##
##----------------##
unless(GetOptions(\%argv,
qw(
debug|d
manual
test=s@
verbose
)))
{
print "USAGE: $0\n";
print " --debug Enable script debug mode\n";
print " --manual Also run disabled tests\n";
print " --smoke Run smoke tests then exit\n";
print " --test Run a list of tests by function name\n";
print " --verbose Enable script verbose mode\n";
exit 1;
}
init();
smoke();
check_makemakefile();
check_makemakefile_distinct();
check_makemakefile_legacy();

Просмотреть файл

@ -0,0 +1,519 @@
#!/usr/bin/env perl
###########################################################################
## Intent: Unit test to verify the makemakefile.pm module
###########################################################################
##----------------------------##
##---] CORE/CPAN INCLUDES [---##
##----------------------------##
use strict;
use warnings;
#use feature 'state';
use Getopt::Long;
use FindBin;
use Cwd qw{abs_path};
use File::Basename;
use File::Compare;
use File::Copy;
use File::Temp qw{tempdir};
use Test;
sub BEGIN { plan tests => 36 };
my @workdirs;
sub END { system("/bin/rm -fr @workdirs"); } # cleanup behind interrupts
##-------------------##
##---] EXPORTS [---##
##-------------------##
our $VERSION = qw(1.0);
##------------------##
##---] INCLUDES [---##
##------------------##
use FindBin;
use lib "$FindBin::RealBin/..";
use makemakefile;
##-------------------##
##---] GLOBALS [---##
##-------------------##
my %argv;
###########################################################################
## Intent: Create a temp sandbox populated with sources
## -----------------------------------------------------------------------
## Args:
## array files to copy into the temporary sandbox
## Returns:
## $@ set on error
## array
## top - path to temp sandbox root
## obj - path to temp sandbox moz_obj directory
## -----------------------------------------------------------------------
###########################################################################
my $_root_; # state $root
sub createSandbox
{
# state $root;
my @errors;
unless ($_root_)
{
my @tmp = split(m%/%, $FindBin::RealBin);
splice(@tmp, -3);
$_root_ = join('/', @tmp);
}
my $work = tempdir(CLEANUP=>1);
push(@workdirs, $work);
my @dirs = map{ join('/', $work, dirname($_)) } @_;
mkdirr(@dirs);
push(@errors, "createSandbox: $@") if ($@);
foreach (@_)
{
## Copy sources into the temp source directory
my $src = join('/', $_root_, $_);
my $dst = join('/', $work, $_);
unless (copy($src, $dst))
{
push(@errors, "copy($src, $dst) failed: $!");
}
}
print STDERR "createSandbox: $work\n" if ($main::argv{debug});
$@ = join('', map{ "$_\n" } @errors);
$work;
} # createSandbox
###########################################################################
## Intent: Verify legacy dirname function
###########################################################################
sub check_dirname_legacy
{
print "Running: check_dirname_legacy\n" if ($main::argv{debug});
foreach (
['/dev/null', '/dev'],
['/foo/bar/Makefile', '/foo/bar'],
)
{
my ($src, $exp) = @{ $_ };
my $dir = dirname_legacy($src);
ok($dir, $exp, "dirname_legacy($src) failed");
}
my $path = dirname_legacy(undef);
ok($path ? 1 : 0, 1, "dirname('') should expand to cwd");
} # check_dirname_legacy
###########################################################################
## Intent: Verify topdir lookup function
###########################################################################
sub check_getTopDir
{
print "Running: check_getTopDir\n" if ($main::argv{debug});
my $path = getTopDir();
## Unit test is special, cmd not invoked from the same directory
## as the makemakefile.pm module.
ok($path ? 1 : 0, 1, "getTopDir failed");
ok(-d $path ? 1 : 0, 1, "getTopDir: directory $path does not exist");
ok($FindBin::RealBin =~ m%$path/% ? 1 : 0, 1, 'Invalid topdir path');
ok(-e "$path/client.mk" ? 1 : 0, 1, "client.mk not found in $path");
} # check_getTopDir
###########################################################################
## Intent: Verify objdir lookup function
###########################################################################
sub check_getObjDir
{
print "Running: check_getObjDir\n" if ($main::argv{debug});
local $main::argv{obj} = '/bin';
my $path = getObjDir('_reset_');
ok($path ? 1 : 0, 1, "getObjDir failed");
ok(-d $path ? 1 : 0, 1, "getObjDir: directory $path does not exist");
my $top = getTopDir();
$main::argv{obj} = join('/', $top, 'browser'); # use existing path so file can be resolved
my $obj = getObjDir('_reset_');
ok($top ne $obj ? 1 : 0, 1, "top and object directory paths should not match");
## If we fail for /bin use here getObjDir() was not reset
my $client = join('/', $obj, '..', 'client.mk');
ok(-e $client ? 1 : 0, 1, "client.mk not found in parent of $path, $client");
getObjDir('_set_'); # clear cached value and recompute
foreach my $file ("$top/memory/mozalloc/Makefile")
{
my $obj = getObjDir('_reset_', $file);
ok($obj ne $file ? 1 : 0, 1, "getObjDir($file) failed")
}
} # check_getObjDir
###########################################################################
## Intent: Verify rel-path-to-root/getdepth function
###########################################################################
sub check_getDepth
{
my @tmp = split(m%/%o, $FindBin::Bin);
splice(@tmp, -3);
my $root = abs_path( join('/', @tmp) );
my %data =
(
$root => '.',
join('/', $root, 'netwerk/Makefile.in') => '..',
join('/', $root, 'browser/components/privatebrowsing/test/browser/Makefile.in') => '../../../../..',
join('/', $root, 'browser/components/privatebrowsing/test/browser/') => '../../../../..',
join('/', $root, 'browser/components/privatebrowsing/test/browser') => '../../../../..',
join('/', $root, 'browser/components/privatebrowsing/test') => '../../../..',
);
while (my($k, $v) = each %data)
{
my $depth = makemakefile::getDepth($k);
ok($depth, $v, "getDepth($k) failed");
}
} # check_getDepth
###########################################################################
## Intent: Verify reading the exclusion file
###########################################################################
sub check_getExclusions
{
my $cfg = join('/', $FindBin::RealBin, 'make-makefile.excl');
my %excl = getExclusions($cfg);
ok($@, '', '$@ should not be set');
my @excl = sort keys %excl;
ok(scalar @excl, 4, "Exclusion file is invalid: \@excl=@excl");
} # check_getExclusions
###########################################################################
## Intent: Verify rel-path-to-root function
## -----------------------------------------------------------------------
## Args:
## none
## Returns:
## none
## -----------------------------------------------------------------------
## Note:
## String test only, top and obj paths are bogus for this test
###########################################################################
sub check_getRelPath
{
my @tmp = split(m%/%o, $FindBin::Bin);
splice(@tmp, -3);
my $root = abs_path( join('/', @tmp) );
my $obj0 = 'obj-arch';
my $obj = join('/', $root, $obj0);
local $main::argv{top} = $root;
local $main::argv{obj} = $obj;
getTopDir('_reset_');
getObjDir('_set_', $obj);
## Cannot test relative paths with objdir beneath /tmp
## Commented paths are needed for full test coverage
## but are not currently supported by all module functions.
my %data =
(
# Relative - path correct for build directory but
'profile/dirserviceprovider/public/Makefile.in' => 'profile/dirserviceprovider/public',
join('/', $root, 'profile/dirserviceprovider/public/Makefile.in') => 'profile/dirserviceprovider/public',
# File search
'profile/dirserviceprovider/public' => 'profile/dirserviceprovider/public',
# cwd + cleanup
# '../../../profile/dirserviceprovider/public/Makefile.in' => 'profile/dirserviceprovider/public',
# "../../../${obj0}/profile/dirserviceprovider/public/Makefile.in" => 'profile/dirserviceprovider/public',
## Special case: This could be handled but permutations of non-existent files, non-overlapping paths
## and relative paths containing partial subdirectories will compilicate the logic. Wait until needed.
## Relative path: $root + obj + subdir
# "${obj0}/profile/dirserviceprovider/public/Makefile" => 'profile/dirserviceprovider/public',
join('/', $obj, 'profile/dirserviceprovider/public/Makefile') => 'profile/dirserviceprovider/public',
# $RealBin, -d ../../..
# top and obj not subdirectories of each other: /foo/x, /bar/y
);
while (my($k, $v) = each %data)
{
my $dir = getRelPath($k);
ok($@, '', '$@ should not be set');
ok($dir, $v, "ERROR[$k]: exp[$v] != found=[$dir]");
}
my $top = '/tmp/foo';
my $tmp = '/tmp/bar';
local $main::argv{top} = $tmp;
local $main::argv{obj} = $obj;
%data =
(
# "$top/profile/dirserviceprovider/public/Makefile.in" => 'profile/dirserviceprovider/public',
"$obj/profile/dirserviceprovider/public/Makefile" => 'profile/dirserviceprovider/public',
);
while (my($k, $v) = each %data)
{
my $dir = getRelPath($k);
ok($dir, $v, "ERROR[$k]: exp[$v] != found=[$dir]");
}
} # check_getRelPath
###########################################################################
## Intent: Verify rel-path-to-root directory creation
###########################################################################
sub check_mkdirr
{
if (-w '/bin') # cygwin may be writable
{
ok(1, 1, 'bogus test to maintain count');
} else {
mkdirr('/bin/invalid/Makefile');
ok($@ ? 1 : 0, 1, '$@ should be set');
}
my $work = createSandbox();
my @paths = map{ join('/', $work, $_, 'Makefile.in') } qw (xyz/abc foo/bar a/b/c/d/e);
mkdirr(@paths);
ok($@ ? 1 : 0, 0, '$@ should not be set');
push(@paths, '/bin');
my @errors;
foreach (@paths)
{
my $dir = dirname($_);
next if (-d $dir);
push(@errors, "mkdirr($dir) failed\n");
}
ok(scalar @errors, 0, "Errors detected: @errors");
} # check_mkdirr
###########################################################################
## Intent: Verify permutations for system("config.status")
###########################################################################
sub check_run_config_status
{
print STDERR "Running: check_run_config_status()\n"
if ($main::argv{debug});
my $work = createSandbox();
chdir $work;
run_config_status();
ok($@ ? 1 : 0, '$@ should be set, config.status does not exist');
my $cfg = join('/', $work, 'config.status');
local *CFG;
open(CFG, "> $cfg") && close(CFG);
run_config_status();
ok($@, qr/config.status failed/, '$@ should be set, config.status is not executabl');
open(CFG, "> $cfg");
print CFG join("\n",
'#!/bin/sh',
'',
'true',
'');
close(CFG);
chmod 0555, $cfg;
run_config_status();
ok($@, qr/config.status failed/, '$@ should not be set');
} # check_run_config_status
###########################################################################
## Intent: Verify makefile generation by legacy make-makefile functions
## o make-makefile -t /x/y -d ..
###########################################################################
sub check_update_makefiles_legacy
{
print STDERR "Running: check_update_makefiles_legacy()\n"
if ($main::argv{debug});
return unless ($argv{legacy});
print STDERR "check_update_makefiles_legacy: not yet implemented\n";
} # check_update_makefiles_legacy
###########################################################################
## Intent: Verify updateMakefiles()
## o a makefile is generated when none exists.
## o a makefile will only be updated when the templates changes.
## o existing makefiles will be updated when the template changes.
## o @foo@ tokens have been expanded
###########################################################################
sub check_updateMakefiles
{
my @errors;
print STDERR "Running: check_updateMakefiles()\n"
if ($main::argv{debug});
my $mf = 'memory/mozalloc/Makefile.in';
my $work = createSandbox($mf);
my $obj = join('/', $work, 'obj');
my %args =
(
top => $work,
obj => $obj,
);
my $mf_src = join('/', $work, 'memory/mozalloc/Makefile.in');
my $mf_dst = join('/', $obj, 'memory/mozalloc/Makefile');
updateMakefiles('memory/mozalloc', \%args);
my $tlm0 = (stat $mf_dst)[9] || 0;
ok(-e $mf_dst ? 1 : 0, 1, "failed to generate makefile: $mf_dst");
#############################
## Regeneration will be a nop
#############################
updateMakefiles('memory/mozalloc', \%args);
my $tlm1 = (stat $mf_dst)[9] || -1;
ok($tlm1, $tlm0, "makefile should not have been modified");
#####################################################
## Modify template to verify makefile will regenerate
#####################################################
local *MF;
if (open(MF, ">> $mf_src"))
{
print MF map{ "# MODIFIED MAKEFILE\n" } 0..4;
close(MF);
}
updateMakefiles('memory/mozalloc', \%args);
my @data = makemakefile::cat($mf_dst);
## Check content to avoid a silly 'sleep [n]' call here
ok(grep(/^\# MODIFIED MAKEFILE/o, @data) ? 1 : 0,
1,
"template modified, makefile should have regenerated");
## VERIFY template expansion
my @gen = makemakefile::cat($mf_dst);
push(@errors, $@) if ($@);
foreach (@gen)
{
if (/\@[^\@]+\@/o)
{
push(@errors, join("\n",
"Unexpanded template string detected [$_]",
"Makefile: $mf_src",
));
last;
}
}
ok(scalar(@errors), 0, "Errors detected: @errors");
} # check_updateMakefiles
###########################################################################
## Intent: Verify makefile generation by updateMakefiles() when
## command line arguments --top and --obj were passed.
###########################################################################
sub check_updateMakefilesByTopObj
{
my @errors;
print STDERR "Running: check_updateMakefilesByTopObj()\n"
if ($main::argv{debug});
my $work = createSandbox();
my %args =
(
top => $work,
obj => $work,
);
## Grab a list of makefile templates to generate
my @all = glob('data/mf.*');
my @src = map{ /\.exp$/o ? () : $_ } @all;
foreach my $src (@src)
{
my $dst = join('/', $work, 'Makefile');
unlink $dst;
copy($src, "$work/Makefile.in");
updateMakefiles('.', \%args);
ok($@, '', '$@ should not be set');
my @dst = makemakefile::cat($dst);
my $exp = join('.', $src, 'exp');
my @exp = makemakefile::cat($exp);
ok("@dst", "@exp", "updateMakefile($dst) failed");
}
return;
} # check_updateMakefilesByTopObj
###########################################################################
## Intent: Smoke tests for the unittests module
###########################################################################
sub smoke
{
print STDERR "Running test: smoke()\n" if ($argv{debug});
} # smoke()
###########################################################################
## Intent: Intitialize global test objects and consts
###########################################################################
sub init
{
print "Running: init()\n" if ($argv{debug});
# testplan(24, 0);
my @path = split(m%/%, $FindBin::RealBin);
splice(@path, -3);
my $top = join('/', @path);
## Top set based on make-makefile startup directory so adjust for test/ use
getTopDir('_set_', $top);
} # init()
##----------------##
##---] MAIN [---##
##----------------##
unless(GetOptions(\%argv,
qw(
debug|d
manual
test=s@
verbose
)))
{
print "USAGE: $0\n";
print " --debug Enable script debug mode\n";
print " --manual Also run disabled tests\n";
print " --smoke Run smoke tests then exit\n";
print " --test Run a list of tests by function name\n";
print " --verbose Enable script verbose mode\n";
exit 1;
}
init();
smoke();
check_dirname_legacy();
check_getTopDir();
check_getObjDir();
check_getDepth();
check_getExclusions();
check_getRelPath();
check_mkdirr();
check_updateMakefiles();
check_update_makefiles_legacy();
check_updateMakefilesByTopObj();

Просмотреть файл

@ -0,0 +1,95 @@
#!/usr/bin/env perl
###########################################################################
## Intent:
## Test::Harness is a testing wrapper that will process output
## from Test.pm module tests. Sumarize results, report stats
## and exit with overall status for the testing suites.
##
## Run testing suite:
## % make clean test
## % perl runtest
##
## Run Individual tests
## % perl tUtils0
###########################################################################
##----------------------------##
##---] CORE/CPAN INCLUDES [---##
##----------------------------##
use strict;
use warnings;
use Getopt::Long;
use Test::Harness;
##-------------------##
##---] EXPORTS [---##
##-------------------##
our $VERSION = qw(1.0);
use FindBin;
##-------------------##
##---] GLOBALS [---##
##-------------------##
my %argv;
##----------------##
##---] MAIN [---##
##----------------##
unless(GetOptions(\%argv,
qw(debug|d)
))
{
print "Usage: $0\n";
print " --debug Enable debug mode\n";
exit 1;
}
if (2 > $Test::Harness::VERSION)
{
print "Unit tests will not be run, Test::Harness is too old\n"
if ($argv{debug});
exit 0;
}
my @tests;
########################################
## Gather a list of tests if none passed
########################################
unless (@tests = @ARGV)
{
local *D;
opendir(D, '.');
while($_ = readdir(D)) {
next unless /.t\S+$/;
next if (/\.ts$/);
push(@tests, $_);
}
closedir(D);
}
###############################################
## Glob a list of tests when directories passed
###############################################
my @tmp;
foreach (@tests)
{
local *D;
if (-d $_ && (my $dir = $_))
{
opendir(D, $_) || die "opendir(D) failed: $!";
my @tests = grep(/\.t[^\.\s]+/o, readdir(D));
closedir(D);
push(@tmp, map{ join('/', $dir, $_); } @tests);
} else {
push(@tmp, $_);
}
}
@tests = @tmp;
print "$0: @ARGV\n" if ($argv{debug});
runtests(@tests);
# EOF

Просмотреть файл

@ -16,5 +16,6 @@
__malloc_hook;
__realloc_hook;
__memalign_hook;
_IO_stdin_used;
local: *;
};

Просмотреть файл

@ -109,3 +109,10 @@ endif
endif # ! MOZ_DEBUG
endif # WIN32_REDIST_DIR
# run the binscope tool to make sure the binary and all libraries
# are using all available Windows OS-level security mechanisms
check::
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/firefox.exe $(DIST)/crashreporter-symbols/
$(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/plugin-container.exe $(DIST)/crashreporter-symbols/

108
build/win32/autobinscope.py Normal file
Просмотреть файл

@ -0,0 +1,108 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (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.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# imelven@mozilla.com
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# run Microsoft's Binscope tool (http://www.microsoft.com/download/en/details.aspx?id=11910)
# against a fresh Windows build. output a 'binscope.log' file with full details
# of the run and appropriate strings to integrate with the buildbots
# from the docs : "The error code returned when running under the command line is equal
# to the number of failures the tool reported plus the number of errors. BinScope will return
# 0 only if there are no errors or failures."
# the symbol dir should point to the symbol dir hierarchy created
# via running make buildsymbols in a windows build's objdir
import sys
import subprocess
import os
BINSCOPE_OUTPUT_LOGFILE = r".\binscope_xml_output.log"
# usage
if len(sys.argv) < 3:
print """usage : autobinscope.by path_to_binary path_to_symbols [log_file_path]"
log_file_path is optional, log will be written to .\binscope_xml_output.log by default"""
sys.exit(0)
binary_path = sys.argv[1]
symbol_path = sys.argv[2]
if len(sys.argv) == 4:
log_file_path = sys.argv[3]
else:
log_file_path = BINSCOPE_OUTPUT_LOGFILE
# execute binscope against the binary, using the BINSCOPE environment
# variable as the path to binscope.exe
try:
binscope_path = os.environ['BINSCOPE']
except KeyError:
print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status."
sys.exit(0)
try:
proc = subprocess.Popen([binscope_path, "/target", binary_path,
"/output", log_file_path, "/sympath", symbol_path,
"/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "FunctionPointersCheck",
"/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
"/c", "GSCheck", "/c", "GSFunctionSafeBuffersCheck", "/c", "GSFriendlyInitCheck",
"/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck",
"/c", "DBCheck"], stdout=subprocess.PIPE)
except WindowsError, (errno, strerror):
if errno != 2 and errno != 3:
print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n"
sys.exit(0)
else:
print "Could not locate binscope at location : %s\n" % binscope_path
print "Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting..."
sys.exit(0)
proc.wait()
output = proc.communicate()[0]
# is this a PASS or a FAIL ?
if proc.returncode != 0:
print "TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path
else:
print "TEST-PASS | autobinscope.py | %s succeeded" % binary_path

Просмотреть файл

@ -819,9 +819,7 @@ nsContentSink::ProcessLink(nsIContent* aElement,
const nsSubstring& aRel, const nsSubstring& aTitle,
const nsSubstring& aType, const nsSubstring& aMedia)
{
// XXX seems overkill to generate this string array
nsTArray<nsString> linkTypes;
nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(aRel);
// The link relation may apply to a different resource, specified
// in the anchor parameter. For the link relations supported so far,
@ -831,22 +829,22 @@ nsContentSink::ProcessLink(nsIContent* aElement,
return NS_OK;
}
bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
bool hasPrefetch = linkTypes & PREFETCH;
// prefetch href if relation is "next" or "prefetch"
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
if (hasPrefetch || (linkTypes & NEXT)) {
PrefetchHref(aHref, aElement, hasPrefetch);
}
if ((!aHref.IsEmpty()) && linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
if (!aHref.IsEmpty() && (linkTypes & DNS_PREFETCH)) {
PrefetchDNS(aHref);
}
// is it a stylesheet link?
if (!linkTypes.Contains(NS_LITERAL_STRING("stylesheet"))) {
if (!(linkTypes & STYLESHEET)) {
return NS_OK;
}
bool isAlternate = linkTypes.Contains(NS_LITERAL_STRING("alternate"));
bool isAlternate = linkTypes & ALTERNATE;
return ProcessStyleLink(aElement, aHref, isAlternate, aTitle, aType,
aMedia);
}

Просмотреть файл

@ -1782,31 +1782,38 @@ IdentifierMapEntryTraverse(nsIdentifierMapEntry *aEntry, void *aArg)
}
static const char* kNSURIs[] = {
" ([none])",
" (xmlns)",
" (xml)",
" (xhtml)",
" (XLink)",
" (XSLT)",
" (XBL)",
" (MathML)",
" (RDF)",
" (XUL)"
"([none])",
"(xmlns)",
"(xml)",
"(xhtml)",
"(XLink)",
"(XSLT)",
"(XBL)",
"(MathML)",
"(RDF)",
"(XUL)"
};
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
if (NS_UNLIKELY(cb.WantDebugInfo())) {
char name[512];
nsCAutoString loadedAsData;
if (tmp->IsLoadedAsData()) {
loadedAsData.AssignLiteral("data");
} else {
loadedAsData.AssignLiteral("normal");
}
PRUint32 nsid = tmp->GetDefaultNamespaceID();
nsCAutoString uri;
if (tmp->mDocumentURI)
tmp->mDocumentURI->GetSpec(uri);
if (nsid < ArrayLength(kNSURIs)) {
PR_snprintf(name, sizeof(name), "nsDocument%s %s", kNSURIs[nsid],
uri.get());
PR_snprintf(name, sizeof(name), "nsDocument %s %s %s",
loadedAsData.get(), kNSURIs[nsid], uri.get());
}
else {
PR_snprintf(name, sizeof(name), "nsDocument %s", uri.get());
PR_snprintf(name, sizeof(name), "nsDocument %s %s",
loadedAsData.get(), uri.get());
}
cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsDocument), name);
}

Просмотреть файл

@ -107,6 +107,7 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
#ifdef ANDROID
#include "nsXULAppAPI.h"
#include "mozilla/Preferences.h"
#endif
class nsAsyncInstantiateEvent : public nsRunnable {
@ -1066,11 +1067,7 @@ nsObjectLoadingContent::ObjectState() const
case eType_Image:
return ImageState();
case eType_Plugin:
#ifdef ANDROID
if (XRE_GetProcessType() == GeckoProcessType_Content)
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
#endif
case eType_Document:
case eType_Document:
// These are OK. If documents start to load successfully, they display
// something, and are thus not broken in this sense. The same goes for
// plugins.
@ -1966,8 +1963,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
{
#ifdef ANDROID
if (XRE_GetProcessType() == GeckoProcessType_Content)
return ePluginClickToPlay;
// if plugins are disabled, don't show the click to play message
if (!mozilla::Preferences::GetBool("plugin.disable", false) &&
XRE_GetProcessType() == GeckoProcessType_Content)
return ePluginClickToPlay;
#endif
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());

Просмотреть файл

@ -153,14 +153,30 @@ nsStyleLinkElement::SetLineNumber(PRUint32 aLineNumber)
mLineNumber = aLineNumber;
}
void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
nsTArray<nsString>& aResult)
PRUint32 ToLinkMask(const nsAString& aLink)
{
if (aLink.EqualsLiteral("prefetch"))
return PREFETCH;
else if (aLink.EqualsLiteral("dns-prefetch"))
return DNS_PREFETCH;
else if (aLink.EqualsLiteral("stylesheet"))
return STYLESHEET;
else if (aLink.EqualsLiteral("next"))
return NEXT;
else if (aLink.EqualsLiteral("alternate"))
return ALTERNATE;
else
return 0;
}
PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
{
PRUint32 linkMask = 0;
nsAString::const_iterator start, done;
aTypes.BeginReading(start);
aTypes.EndReading(done);
if (start == done)
return;
return linkMask;
nsAString::const_iterator current(start);
bool inString = !nsCRT::IsAsciiSpace(*current);
@ -170,7 +186,7 @@ void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
if (nsCRT::IsAsciiSpace(*current)) {
if (inString) {
ToLowerCase(Substring(start, current), subString);
aResult.AppendElement(subString);
linkMask |= ToLinkMask(subString);
inString = false;
}
}
@ -184,8 +200,9 @@ void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
}
if (inString) {
ToLowerCase(Substring(start, current), subString);
aResult.AppendElement(subString);
linkMask |= ToLinkMask(subString);
}
return linkMask;
}
NS_IMETHODIMP

Просмотреть файл

@ -53,6 +53,12 @@
#include "nsIURI.h"
#include "nsTArray.h"
#define PREFETCH 0x00000001
#define DNS_PREFETCH 0x00000002
#define STYLESHEET 0x00000004
#define NEXT 0x00000008
#define ALTERNATE 0x00000010
class nsIDocument;
class nsStyleLinkElement : public nsIDOMLinkStyle,
@ -80,7 +86,7 @@ public:
virtual void OverrideBaseURI(nsIURI* aNewBaseURI);
virtual void SetLineNumber(PRUint32 aLineNumber);
static void ParseLinkTypes(const nsAString& aTypes, nsTArray<nsString>& aResult);
static PRUint32 ParseLinkTypes(const nsAString& aTypes);
void UpdateStyleSheetInternal() { UpdateStyleSheetInternal(nsnull); }
protected:

Просмотреть файл

@ -103,6 +103,7 @@
#include "nsStringBuffer.h"
#include "nsDOMFile.h"
#include "nsIFileChannel.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
@ -1485,6 +1486,8 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
// No optional arguments were passed in. Default async to true.
async = true;
}
Telemetry::Accumulate(Telemetry::XMLHTTPREQUEST_ASYNC_OR_SYNC,
async ? 0 : 1);
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);

Просмотреть файл

@ -301,16 +301,17 @@ WebGLContext::WebGLContext()
mContextLost = false;
mAllowRestore = false;
mRobustnessTimerRunning = false;
mDrawSinceRobustnessTimerSet = false;
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
}
WebGLContext::~WebGLContext()
{
DestroyResourcesAndContext();
WebGLMemoryReporter::RemoveWebGLContext(this);
if (mContextRestorer) {
mContextRestorer->Cancel();
mContextRestorer = NULL;
}
TerminateRobustnessTimer();
mContextRestorer = nsnull;
}
static PLDHashOperator
@ -709,6 +710,8 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
mResetLayer = true;
mOptionsFrozen = true;
mHasRobustness = gl->HasRobustness();
// increment the generation number
++mGeneration;
@ -1147,13 +1150,8 @@ WebGLContext::EnsureBackbufferClearedAsNeeded()
NS_IMETHODIMP
WebGLContext::Notify(nsITimer* timer)
{
TerminateRobustnessTimer();
MaybeRestoreContext();
if (mContextRestorer) {
mContextRestorer->Cancel();
mContextRestorer = NULL;
}
return NS_OK;
}
@ -1163,6 +1161,7 @@ WebGLContext::MaybeRestoreContext()
if (mContextLost || mAllowRestore)
return;
gl->MakeCurrent();
GLContext::ContextResetARB resetStatus =
(GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
@ -1174,6 +1173,11 @@ WebGLContext::MaybeRestoreContext()
switch (resetStatus) {
case GLContext::CONTEXT_NO_ERROR:
// If there has been activity since the timer was set, it's possible
// that we did or are going to miss something, so clear this flag and
// run it again some time later.
if (mDrawSinceRobustnessTimerSet)
SetupRobustnessTimer();
return;
case GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page caused the graphics card to reset; not restoring the context");
@ -1191,10 +1195,7 @@ WebGLContext::MaybeRestoreContext()
void
WebGLContext::ForceLoseContext()
{
if (mContextRestorer) {
mContextRestorer->Cancel();
mContextRestorer = NULL;
}
TerminateRobustnessTimer();
mWebGLError = LOCAL_GL_CONTEXT_LOST;

Просмотреть файл

@ -449,17 +449,30 @@ public:
// Sets up the GL_ARB_robustness timer if it isn't already, so that if the
// driver gets restarted, the context may get reset with it.
void SetupRobustnessTimer() {
if (mContextLost)
if (mContextLost || !mHasRobustness)
return;
if (!mContextRestorer)
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
// If the timer was already running, don't restart it here. Instead,
// wait until the previous call is done, then fire it one more time.
// This is an optimization to prevent unnecessary cross-communication
// between threads.
if (mRobustnessTimerRunning) {
mDrawSinceRobustnessTimerSet = true;
return;
}
// As long as there's still activity, we reset the timer each time that
// this function gets called.
mContextRestorer->InitWithCallback(static_cast<nsITimerCallback*>(this),
PR_MillisecondsToInterval(1000),
nsITimer::TYPE_ONE_SHOT);
mRobustnessTimerRunning = true;
mDrawSinceRobustnessTimerSet = false;
}
void TerminateRobustnessTimer() {
if (mRobustnessTimerRunning) {
mContextRestorer->Cancel();
mRobustnessTimerRunning = false;
}
}
protected:
@ -504,6 +517,7 @@ protected:
bool mOptionsFrozen;
bool mMinCapability;
bool mDisableExtensions;
bool mHasRobustness;
WebGLuint mActiveTexture;
WebGLenum mWebGLError;
@ -723,6 +737,8 @@ protected:
nsCOMPtr<nsITimer> mContextRestorer;
bool mContextLost;
bool mAllowRestore;
bool mRobustnessTimerRunning;
bool mDrawSinceRobustnessTimerSet;
public:
// console logging helpers

Просмотреть файл

@ -1622,8 +1622,6 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
if (!ValidateBuffers(&maxAllowedCount, "drawArrays"))
return NS_OK;
SetupRobustnessTimer();
CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
if (!checked_firstPlusCount.valid())
@ -1645,6 +1643,7 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
if (!DoFakeVertexAttrib0(checked_firstPlusCount.value()))
return NS_OK;
SetupRobustnessTimer();
gl->fDrawArrays(mode, first, count);
UndoFakeVertexAttrib0();
@ -1675,8 +1674,6 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
if (count == 0)
return NS_OK;
SetupRobustnessTimer();
CheckedUint32 checked_byteCount;
if (type == LOCAL_GL_UNSIGNED_SHORT) {
@ -1757,6 +1754,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
if (!DoFakeVertexAttrib0(checked_maxIndexPlusOne.value()))
return NS_OK;
SetupRobustnessTimer();
gl->fDrawElements(mode, count, type, (GLvoid*) (byteOffset));
UndoFakeVertexAttrib0();

Просмотреть файл

@ -61,7 +61,7 @@ NS_IMETHODIMP
WebGLExtensionLoseContext::LoseContext()
{
if (!mContext->LoseContext())
return mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
return NS_OK;
}
@ -70,7 +70,7 @@ NS_IMETHODIMP
WebGLExtensionLoseContext::RestoreContext()
{
if (!mContext->RestoreContext())
return mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
return NS_OK;
}

Просмотреть файл

@ -3650,8 +3650,8 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
return res.mIsStillLoading ? NS_OK : NS_ERROR_NOT_AVAILABLE;
}
// Ignore nsnull cairo surfaces! See bug 666312.
if (!res.mSurface->CairoSurface()) {
// Ignore cairo surfaces that are bad! See bug 666312.
if (res.mSurface->CairoStatus()) {
return NS_OK;
}

Просмотреть файл

@ -134,10 +134,9 @@ function testFailedRender(msg, ref, test, width, height)
testFailed(msg);
var data = 'REFTEST TEST-KNOWN-FAIL | ' + msg + ' | image comparison (==)\n' +
var data = 'REFTEST TEST-DEBUG-INFO | ' + msg + ' | image comparison (==)\n' +
'REFTEST IMAGE 1 (TEST): ' + testData + '\n' +
'REFTEST IMAGE 2 (REFERENCE): ' + refData;
dump('The following information is for debugging purposes only. It will always print TEST-KNOWN-FAIL, even if it is unexpected.');
dump('FAIL: ' + data + '\n');
dump('To view the differences between these image renderings, go to the following link: https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml#log=' +
encodeURIComponent(encodeURIComponent(data)) + '\n');

Просмотреть файл

@ -307,9 +307,8 @@ nsHTMLLinkElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
bool dropSheet = false;
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::rel &&
GetStyleSheet()) {
nsAutoTArray<nsString, 4> linkTypes;
nsStyleLinkElement::ParseLinkTypes(aValue, linkTypes);
dropSheet = !linkTypes.Contains(NS_LITERAL_STRING("stylesheet"));
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(aValue);
dropSheet = !(linkTypes & STYLESHEET);
}
UpdateStyleSheetInternal(nsnull,
@ -413,11 +412,10 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
*aIsAlternate = false;
nsAutoString rel;
nsAutoTArray<nsString, 4> linkTypes;
GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
nsStyleLinkElement::ParseLinkTypes(rel, linkTypes);
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
// Is it a stylesheet link?
if (!linkTypes.Contains(NS_LITERAL_STRING("stylesheet"))) {
if (!(linkTypes & STYLESHEET)) {
return;
}
@ -427,7 +425,7 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
aTitle.Assign(title);
// If alternate, does it have title?
if (linkTypes.Contains(NS_LITERAL_STRING("alternate"))) {
if (linkTypes & ALTERNATE) {
if (aTitle.IsEmpty()) { // alternates must have title
return;
} else {

Просмотреть файл

@ -2644,18 +2644,16 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
nsAutoString relVal;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
if (!relVal.IsEmpty()) {
// XXX seems overkill to generate this string array
nsAutoTArray<nsString, 4> linkTypes;
nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
bool hasPrefetch = linkTypes & PREFETCH;
if (hasPrefetch || (linkTypes & NEXT)) {
nsAutoString hrefVal;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchHref(hrefVal, element, hasPrefetch);
}
}
if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
if (linkTypes & DNS_PREFETCH) {
nsAutoString hrefVal;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {

Просмотреть файл

@ -950,6 +950,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
// Set the parser as the stream listener for the document loader...
if (mParser) {
rv = NS_OK;
nsCOMPtr<nsIStreamListener> listener = mParser->GetStreamListener();
listener.forget(aDocListener);

Просмотреть файл

@ -90,13 +90,12 @@ public:
// nsScriptElement
virtual bool HasScriptContent();
// nsSVGElement specializations:
virtual void DidChangeString(PRUint8 aAttrEnum);
// nsIContent specializations:
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers);
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
const nsAString* aValue, bool aNotify);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@ -252,16 +251,6 @@ nsSVGScriptElement::HasScriptContent()
//----------------------------------------------------------------------
// nsSVGElement methods
void
nsSVGScriptElement::DidChangeString(PRUint8 aAttrEnum)
{
nsSVGScriptElementBase::DidChangeString(aAttrEnum);
if (aAttrEnum == HREF) {
MaybeProcessScript();
}
}
nsSVGElement::StringAttributesInfo
nsSVGScriptElement::GetStringInfo()
{
@ -289,3 +278,13 @@ nsSVGScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
return NS_OK;
}
nsresult
nsSVGScriptElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
const nsAString* aValue, bool aNotify)
{
if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
MaybeProcessScript();
}
return nsSVGScriptElementBase::AfterSetAttr(aNamespaceID, aName,
aValue, aNotify);
}

Просмотреть файл

@ -646,18 +646,16 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
nsAutoString relVal;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
if (!relVal.IsEmpty()) {
// XXX seems overkill to generate this string array
nsAutoTArray<nsString, 4> linkTypes;
nsStyleLinkElement::ParseLinkTypes(relVal, linkTypes);
bool hasPrefetch = linkTypes.Contains(NS_LITERAL_STRING("prefetch"));
if (hasPrefetch || linkTypes.Contains(NS_LITERAL_STRING("next"))) {
PRUint32 linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
bool hasPrefetch = linkTypes & PREFETCH;
if (hasPrefetch || (linkTypes & NEXT)) {
nsAutoString hrefVal;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchHref(hrefVal, aContent, hasPrefetch);
}
}
if (linkTypes.Contains(NS_LITERAL_STRING("dns-prefetch"))) {
if (linkTypes & DNS_PREFETCH) {
nsAutoString hrefVal;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {

Просмотреть файл

@ -106,10 +106,4 @@ public:
static double toDouble(const nsAString& aStr);
};
// XXX These should go away eventually.
#define TxObject txObject
typedef txDouble Double;
// XXX
#endif

Просмотреть файл

@ -50,20 +50,20 @@
*/
//-- Initialize Double related constants
const dpun Double::NaN = DOUBLE_NaN;
const dpun txDouble::NaN = DOUBLE_NaN;
#ifdef IS_BIG_ENDIAN
const dpun Double::POSITIVE_INFINITY = {{DOUBLE_HI32_EXPMASK, 0}};
const dpun Double::NEGATIVE_INFINITY = {{DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT, 0}};
const dpun txDouble::POSITIVE_INFINITY = {{DOUBLE_HI32_EXPMASK, 0}};
const dpun txDouble::NEGATIVE_INFINITY = {{DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT, 0}};
#else
const dpun Double::POSITIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK}};
const dpun Double::NEGATIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT}};
const dpun txDouble::POSITIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK}};
const dpun txDouble::NEGATIVE_INFINITY = {{0, DOUBLE_HI32_EXPMASK | DOUBLE_HI32_SIGNBIT}};
#endif
/*
* Determines whether the given double represents positive or negative
* inifinity
*/
bool Double::isInfinite(double aDbl)
bool txDouble::isInfinite(double aDbl)
{
return ((DOUBLE_HI32(aDbl) & ~DOUBLE_HI32_SIGNBIT) == DOUBLE_HI32_EXPMASK &&
!DOUBLE_LO32(aDbl));
@ -72,7 +72,7 @@ bool Double::isInfinite(double aDbl)
/*
* Determines whether the given double is NaN
*/
bool Double::isNaN(double aDbl)
bool txDouble::isNaN(double aDbl)
{
return DOUBLE_IS_NaN(aDbl);
}
@ -80,7 +80,7 @@ bool Double::isNaN(double aDbl)
/*
* Determines whether the given double is negative
*/
bool Double::isNeg(double aDbl)
bool txDouble::isNeg(double aDbl)
{
return (DOUBLE_HI32(aDbl) & DOUBLE_HI32_SIGNBIT) != 0;
}
@ -170,7 +170,7 @@ public:
{
if (mState == eIllegal || mBuffer.IsEmpty() ||
(mBuffer.Length() == 1 && mBuffer[0] == '.')) {
return Double::NaN;
return txDouble::NaN;
}
return mSign*PR_strtod(mBuffer.get(), 0);
}
@ -189,7 +189,7 @@ private:
} mSign;
};
double Double::toDouble(const nsAString& aSrc)
double txDouble::toDouble(const nsAString& aSrc)
{
txStringToDouble sink;
nsAString::const_iterator fromBegin, fromEnd;
@ -202,7 +202,7 @@ double Double::toDouble(const nsAString& aSrc)
* The result into the destination String.
* @return the given dest string
*/
void Double::toString(double aValue, nsAString& aDest)
void txDouble::toString(double aValue, nsAString& aDest)
{
// check for special cases

Просмотреть файл

@ -46,7 +46,7 @@ class txListIterator;
/**
* Represents an ordered list of Object pointers. Modeled after a Java 2 List.
**/
class txList : public TxObject {
class txList : public txObject {
friend class txListIterator;

Просмотреть файл

@ -82,7 +82,7 @@ class ProcessingInstruction;
// Abstract Class defining the interface for a Node. See NodeDefinition below
// for the actual implementation of the WC3 node.
//
class Node : public TxObject
class Node : public txObject
{
public:
//Node type constants

Просмотреть файл

@ -396,8 +396,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
NS_ENSURE_SUCCESS(rv, rv);
// check for NaN or +/-Inf
if (Double::isNaN(start) ||
Double::isInfinite(start) ||
if (txDouble::isNaN(start) ||
txDouble::isInfinite(start) ||
start >= src.Length() + 0.5) {
aContext->recycler()->getEmptyStringResult(aResult);
@ -412,7 +412,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
NS_ENSURE_SUCCESS(rv, rv);
end += start;
if (Double::isNaN(end) || end < 0) {
if (txDouble::isNaN(end) || end < 0) {
aContext->recycler()->getEmptyStringResult(aResult);
return NS_OK;
@ -546,7 +546,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
nsAutoString resultStr;
txXPathNodeUtils::appendNodeValue(aContext->getContextNode(),
resultStr);
res = Double::toDouble(resultStr);
res = txDouble::toDouble(resultStr);
}
return aContext->recycler()->getNumberResult(res, aResult);
}
@ -556,8 +556,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = evaluateToNumber(mParams[0], aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv);
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
if (Double::isNeg(dbl) && dbl >= -0.5) {
if (!txDouble::isNaN(dbl) && !txDouble::isInfinite(dbl)) {
if (txDouble::isNeg(dbl) && dbl >= -0.5) {
dbl *= 0;
}
else {
@ -573,9 +573,9 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = evaluateToNumber(mParams[0], aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv);
if (!Double::isNaN(dbl) &&
!Double::isInfinite(dbl) &&
!(dbl == 0 && Double::isNeg(dbl))) {
if (!txDouble::isNaN(dbl) &&
!txDouble::isInfinite(dbl) &&
!(dbl == 0 && txDouble::isNeg(dbl))) {
dbl = floor(dbl);
}
@ -587,8 +587,8 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
rv = evaluateToNumber(mParams[0], aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv);
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
if (Double::isNeg(dbl) && dbl > -1) {
if (!txDouble::isNaN(dbl) && !txDouble::isInfinite(dbl)) {
if (txDouble::isNeg(dbl) && dbl > -1) {
dbl *= 0;
}
else {
@ -610,7 +610,7 @@ txCoreFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
for (i = 0; i < nodes->size(); ++i) {
nsAutoString resultStr;
txXPathNodeUtils::appendNodeValue(nodes->get(i), resultStr);
res += Double::toDouble(resultStr);
res += txDouble::toDouble(resultStr);
}
return aContext->recycler()->getNumberResult(res, aResult);
}

Просмотреть файл

@ -419,7 +419,7 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
break;
case Token::NUMBER:
{
expr = new txLiteralExpr(Double::toDouble(tok->Value()));
expr = new txLiteralExpr(txDouble::toDouble(tok->Value()));
break;
}
default:

Просмотреть файл

@ -103,7 +103,7 @@ txLiteralExpr::toString(nsAString& aStr)
}
case txAExprResult::NUMBER:
{
Double::toString(mValue->numberValue(), aStr);
txDouble::toString(mValue->numberValue(), aStr);
return;
}
case txAExprResult::STRING:

Просмотреть файл

@ -501,7 +501,7 @@ txNodeSet::numberValue()
nsAutoString str;
stringValue(str);
return Double::toDouble(str);
return txDouble::toDouble(str);
}
void

Просмотреть файл

@ -86,7 +86,7 @@ txNodeSetAdaptor::ItemAsNumber(PRUint32 aIndex, double *aResult)
nsAutoString result;
txXPathNodeUtils::appendNodeValue(NodeSet()->get(aIndex), result);
*aResult = Double::toDouble(result);
*aResult = txDouble::toDouble(result);
return NS_OK;
}

Просмотреть файл

@ -70,16 +70,16 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
if (rightDbl == 0) {
#if defined(XP_WIN)
/* XXX MSVC miscompiles such that (NaN == 0) */
if (Double::isNaN(rightDbl))
result = Double::NaN;
if (txDouble::isNaN(rightDbl))
result = txDouble::NaN;
else
#endif
if (leftDbl == 0 || Double::isNaN(leftDbl))
result = Double::NaN;
else if (Double::isNeg(leftDbl) ^ Double::isNeg(rightDbl))
result = Double::NEGATIVE_INFINITY;
if (leftDbl == 0 || txDouble::isNaN(leftDbl))
result = txDouble::NaN;
else if (txDouble::isNeg(leftDbl) ^ txDouble::isNeg(rightDbl))
result = txDouble::NEGATIVE_INFINITY;
else
result = Double::POSITIVE_INFINITY;
result = txDouble::POSITIVE_INFINITY;
}
else
result = leftDbl / rightDbl;
@ -87,12 +87,12 @@ txNumberExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
case MODULUS:
if (rightDbl == 0) {
result = Double::NaN;
result = txDouble::NaN;
}
else {
#if defined(XP_WIN)
/* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
if (!Double::isInfinite(leftDbl) && Double::isInfinite(rightDbl))
if (!txDouble::isInfinite(leftDbl) && txDouble::isInfinite(rightDbl))
result = leftDbl;
else
#endif

Просмотреть файл

@ -67,7 +67,7 @@ short NumberResult::getResultType() {
void
NumberResult::stringValue(nsString& aResult)
{
Double::toString(value, aResult);
txDouble::toString(value, aResult);
}
const nsString*
@ -80,7 +80,7 @@ bool NumberResult::booleanValue() {
// OG+
// As per the XPath spec, the boolean value of a number is true if and only if
// it is neither positive 0 nor negative 0 nor NaN
return (bool)(value != 0.0 && !Double::isNaN(value));
return (bool)(value != 0.0 && !txDouble::isNaN(value));
// OG-
} //-- booleanValue

Просмотреть файл

@ -84,6 +84,6 @@ bool StringResult::booleanValue() {
} //-- booleanValue
double StringResult::numberValue() {
return Double::toDouble(mValue);
return txDouble::toDouble(mValue);
} //-- numberValue

Просмотреть файл

@ -58,7 +58,7 @@ double
txUnionNodeTest::getDefaultPriority()
{
NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
return Double::NaN;
return txDouble::NaN;
}
bool

Просмотреть файл

@ -611,7 +611,7 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
if (nodes->isEmpty()) {
return aContext->recycler()->
getNumberResult(Double::NaN, aResult);
getNumberResult(txDouble::NaN, aResult);
}
bool findMax = mType == MAX;
@ -622,9 +622,9 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
for (i = 0; i < len; ++i) {
nsAutoString str;
txXPathNodeUtils::appendNodeValue(nodes->get(i), str);
double val = Double::toDouble(str);
if (Double::isNaN(val)) {
res = Double::NaN;
double val = txDouble::toDouble(str);
if (txDouble::isNaN(val)) {
res = txDouble::NaN;
break;
}
@ -661,8 +661,8 @@ txEXSLTFunctionCall::evaluate(txIEvalContext *aContext,
nsAutoString str;
const txXPathNode& node = nodes->get(i);
txXPathNodeUtils::appendNodeValue(node, str);
double val = Double::toDouble(str);
if (Double::isNaN(val)) {
double val = txDouble::toDouble(str);
if (txDouble::isNaN(val)) {
resultSet->clear();
break;
}

Просмотреть файл

@ -112,16 +112,16 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
}
// Special cases
if (Double::isNaN(value)) {
if (txDouble::isNaN(value)) {
return aContext->recycler()->getStringResult(format->mNaN, aResult);
}
if (value == Double::POSITIVE_INFINITY) {
if (value == txDouble::POSITIVE_INFINITY) {
return aContext->recycler()->getStringResult(format->mInfinity,
aResult);
}
if (value == Double::NEGATIVE_INFINITY) {
if (value == txDouble::NEGATIVE_INFINITY) {
nsAutoString res;
res.Append(format->mMinusSign);
res.Append(format->mInfinity);
@ -143,7 +143,7 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
// Get right subexpression
inQuote = false;
if (Double::isNeg(value)) {
if (txDouble::isNeg(value)) {
while (pos < formatLen &&
(inQuote ||
formatStr.CharAt(pos) != format->mPatternSeparator)) {

Просмотреть файл

@ -51,7 +51,7 @@
class nsIAtom;
class txExecutionState;
class txInstruction : public TxObject
class txInstruction : public txObject
{
public:
txInstruction()

Просмотреть файл

@ -180,8 +180,8 @@ txNodeSorter::sortNodeSet(txNodeSet* aNodes, txExecutionState* aEs,
PRUint32 len = static_cast<PRUint32>(aNodes->size());
// Limit resource use to something sane.
PRUint32 itemSize = sizeof(PRUint32) + mNKeys * sizeof(TxObject*);
if (mNKeys > (PR_UINT32_MAX - sizeof(PRUint32)) / sizeof(TxObject*) ||
PRUint32 itemSize = sizeof(PRUint32) + mNKeys * sizeof(txObject*);
if (mNKeys > (PR_UINT32_MAX - sizeof(PRUint32)) / sizeof(txObject*) ||
len >= PR_UINT32_MAX / itemSize) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -190,13 +190,13 @@ txNodeSorter::sortNodeSet(txNodeSet* aNodes, txExecutionState* aEs,
NS_ENSURE_TRUE(mem, NS_ERROR_OUT_OF_MEMORY);
PRUint32* indexes = static_cast<PRUint32*>(mem);
TxObject** sortValues = reinterpret_cast<TxObject**>(indexes + len);
txObject** sortValues = reinterpret_cast<txObject**>(indexes + len);
PRUint32 i;
for (i = 0; i < len; ++i) {
indexes[i] = i;
}
memset(sortValues, 0, len * mNKeys * sizeof(TxObject*));
memset(sortValues, 0, len * mNKeys * sizeof(txObject*));
// Sort the indexarray
SortData sortData;
@ -248,9 +248,9 @@ txNodeSorter::compareNodes(const void* aIndexA, const void* aIndexB,
txListIterator iter(&sortData->mNodeSorter->mSortKeys);
PRUint32 indexA = *static_cast<const PRUint32*>(aIndexA);
PRUint32 indexB = *static_cast<const PRUint32*>(aIndexB);
TxObject** sortValuesA = sortData->mSortValues +
txObject** sortValuesA = sortData->mSortValues +
indexA * sortData->mNodeSorter->mNKeys;
TxObject** sortValuesB = sortData->mSortValues +
txObject** sortValuesB = sortData->mSortValues +
indexB * sortData->mNodeSorter->mNKeys;
unsigned int i;
@ -280,7 +280,7 @@ txNodeSorter::compareNodes(const void* aIndexA, const void* aIndexB,
//static
bool
txNodeSorter::calcSortValue(TxObject*& aSortValue, SortKey* aKey,
txNodeSorter::calcSortValue(txObject*& aSortValue, SortKey* aKey,
SortData* aSortData, PRUint32 aNodeIndex)
{
aSortData->mContext->setPosition(aNodeIndex + 1); // position is 1-based

Просмотреть файл

@ -46,7 +46,7 @@
class Expr;
class txExecutionState;
class txNodeSet;
class TxObject;
class txObject;
class txXPathResultComparator;
class txIEvalContext;
class txNodeSetContext;
@ -72,7 +72,7 @@ private:
{
txNodeSorter* mNodeSorter;
txNodeSetContext* mContext;
TxObject** mSortValues;
txObject** mSortValues;
nsresult mRv;
};
struct SortKey
@ -83,8 +83,8 @@ private:
static int compareNodes(const void* aIndexA, const void* aIndexB,
void* aSortData);
static bool calcSortValue(TxObject*& aSortValue, SortKey* aKey,
SortData* aSortData, PRUint32 aNodeIndex);
static bool calcSortValue(txObject*& aSortValue, SortKey* aKey,
SortData* aSortData, PRUint32 aNodeIndex);
txList mSortKeys;
unsigned int mNKeys;
};

Просмотреть файл

@ -77,7 +77,7 @@ double txResultTreeFragment::numberValue()
return 0;
}
return Double::toDouble(mBuffer->mStringValue);
return txDouble::toDouble(mBuffer->mStringValue);
}
nsresult txResultTreeFragment::flushToHandler(txAXMLEventHandler* aHandler)

Просмотреть файл

@ -442,9 +442,9 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
PRUint32 unionPos = 1; // only used when unionPattern is set
while (simple) {
double priority = aTemplate->mPrio;
if (Double::isNaN(priority)) {
if (txDouble::isNaN(priority)) {
priority = simple->getDefaultPriority();
NS_ASSERTION(!Double::isNaN(priority),
NS_ASSERTION(!txDouble::isNaN(priority),
"simple pattern without default priority");
}

Просмотреть файл

@ -128,7 +128,7 @@ public:
ImportFrame* mFirstNotImported;
};
class GlobalVariable : public TxObject {
class GlobalVariable : public txObject {
public:
GlobalVariable(nsAutoPtr<Expr> aExpr,
nsAutoPtr<txInstruction> aFirstInstruction,

Просмотреть файл

@ -303,7 +303,7 @@ getNumberAttr(txStylesheetAttr* aAttributes,
txStylesheetCompilerState& aState,
double& aNumber)
{
aNumber = Double::NaN;
aNumber = txDouble::NaN;
txStylesheetAttr* attr = nsnull;
nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
aName, aRequired, &attr);
@ -311,8 +311,8 @@ getNumberAttr(txStylesheetAttr* aAttributes,
return rv;
}
aNumber = Double::toDouble(attr->mValue);
if (Double::isNaN(aNumber) && (aRequired || !aState.fcp())) {
aNumber = txDouble::toDouble(attr->mValue);
if (txDouble::isNaN(aNumber) && (aRequired || !aState.fcp())) {
// XXX ErrorReport: number parse failure
return NS_ERROR_XSLT_PARSE_FAILURE;
}
@ -552,7 +552,7 @@ txFnStartLREStylesheet(PRInt32 aNamespaceID,
NS_ENSURE_SUCCESS(rv, rv);
txExpandedName nullExpr;
double prio = Double::NaN;
double prio = txDouble::NaN;
nsAutoPtr<txPattern> match(new txRootPattern());
NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY);
@ -1145,7 +1145,7 @@ txFnStartTemplate(PRInt32 aNamespaceID,
aState, mode);
NS_ENSURE_SUCCESS(rv, rv);
double prio = Double::NaN;
double prio = txDouble::NaN;
rv = getNumberAttr(aAttributes, aAttrCount, nsGkAtoms::priority,
false, aState, prio);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -688,15 +688,15 @@ txStylesheetCompilerState::popChooseGotoList()
}
nsresult
txStylesheetCompilerState::pushObject(TxObject* aObject)
txStylesheetCompilerState::pushObject(txObject* aObject)
{
return mObjectStack.push(aObject);
}
TxObject*
txObject*
txStylesheetCompilerState::popObject()
{
return static_cast<TxObject*>(mObjectStack.pop());
return static_cast<txObject*>(mObjectStack.pop());
}
nsresult

Просмотреть файл

@ -60,7 +60,7 @@ class txPushNewContext;
class txStylesheetCompiler;
class txInScopeVariable;
class txElementContext : public TxObject
class txElementContext : public txObject
{
public:
txElementContext(const nsAString& aBaseURI);
@ -122,8 +122,8 @@ public:
void popSorter();
nsresult pushChooseGotoList();
void popChooseGotoList();
nsresult pushObject(TxObject* aObject);
TxObject* popObject();
nsresult pushObject(txObject* aObject);
txObject* popObject();
nsresult pushPtr(void* aPtr);
void* popPtr();

Просмотреть файл

@ -129,7 +129,7 @@ txResultStringComparator::createSortableValue(Expr *aExpr,
return NS_OK;
}
int txResultStringComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
int txResultStringComparator::compareValues(txObject* aVal1, txObject* aVal2)
{
StringValue* strval1 = (StringValue*)aVal1;
StringValue* strval2 = (StringValue*)aVal2;
@ -223,7 +223,7 @@ txResultNumberComparator::txResultNumberComparator(bool aAscending)
nsresult
txResultNumberComparator::createSortableValue(Expr *aExpr,
txIEvalContext *aContext,
TxObject *&aResult)
txObject *&aResult)
{
nsAutoPtr<NumberValue> numval(new NumberValue);
if (!numval) {
@ -241,15 +241,15 @@ txResultNumberComparator::createSortableValue(Expr *aExpr,
return NS_OK;
}
int txResultNumberComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
int txResultNumberComparator::compareValues(txObject* aVal1, txObject* aVal2)
{
double dval1 = ((NumberValue*)aVal1)->mVal;
double dval2 = ((NumberValue*)aVal2)->mVal;
if (Double::isNaN(dval1))
return Double::isNaN(dval2) ? 0 : -mAscending;
if (txDouble::isNaN(dval1))
return txDouble::isNaN(dval2) ? 0 : -mAscending;
if (Double::isNaN(dval2))
if (txDouble::isNaN(dval2))
return mAscending;
if (dval1 == dval2)

Просмотреть файл

@ -62,13 +62,13 @@ public:
* Compares two XPath results. Returns -1 if val1 < val2,
* 1 if val1 > val2 and 0 if val1 == val2.
*/
virtual int compareValues(TxObject* val1, TxObject* val2) = 0;
virtual int compareValues(txObject* val1, txObject* val2) = 0;
/*
* Create a sortable value.
*/
virtual nsresult createSortableValue(Expr *aExpr, txIEvalContext *aContext,
TxObject *&aResult) = 0;
txObject *&aResult) = 0;
};
/*
@ -80,9 +80,9 @@ public:
txResultStringComparator(bool aAscending, bool aUpperFirst,
const nsAFlatString& aLanguage);
int compareValues(TxObject* aVal1, TxObject* aVal2);
int compareValues(txObject* aVal1, txObject* aVal2);
nsresult createSortableValue(Expr *aExpr, txIEvalContext *aContext,
TxObject *&aResult);
txObject *&aResult);
private:
nsCOMPtr<nsICollation> mCollation;
nsresult init(const nsAFlatString& aLanguage);
@ -92,7 +92,7 @@ private:
PRUint32* aLength);
int mSorting;
class StringValue : public TxObject
class StringValue : public txObject
{
public:
StringValue();
@ -112,14 +112,14 @@ class txResultNumberComparator : public txXPathResultComparator
public:
txResultNumberComparator(bool aAscending);
int compareValues(TxObject* aVal1, TxObject* aVal2);
int compareValues(txObject* aVal1, txObject* aVal2);
nsresult createSortableValue(Expr *aExpr, txIEvalContext *aContext,
TxObject *&aResult);
txObject *&aResult);
private:
int mAscending;
class NumberValue : public TxObject
class NumberValue : public txObject
{
public:
double mVal;

Просмотреть файл

@ -122,9 +122,9 @@ txXSLTNumber::getValueList(Expr* aValueExpr, txPattern* aCountPattern,
double value = result->numberValue();
if (Double::isInfinite(value) || Double::isNaN(value) ||
if (txDouble::isInfinite(value) || txDouble::isNaN(value) ||
value < 0.5) {
Double::toString(value, aValueString);
txDouble::toString(value, aValueString);
return NS_OK;
}
@ -318,7 +318,7 @@ txXSLTNumber::getCounters(Expr* aGroupSize, Expr* aGroupSeparator,
rv = aGroupSize->evaluateToString(aContext, sizeStr);
NS_ENSURE_SUCCESS(rv, rv);
double size = Double::toDouble(sizeStr);
double size = txDouble::toDouble(sizeStr);
groupSize = (PRInt32)size;
if ((double)groupSize != size) {
groupSize = 0;

Просмотреть файл

@ -54,7 +54,7 @@
double txUnionPattern::getDefaultPriority()
{
NS_ERROR("Don't call getDefaultPriority on txUnionPattern");
return Double::NaN;
return txDouble::NaN;
}
/*

Просмотреть файл

@ -203,7 +203,7 @@ WifiGeoPositionProvider.prototype = {
let accessToken = this.getAccessTokenForURL(providerUrlBase);
if (accessToken !== "")
providerUrl = providerUrl + "&access_token="+access_token;
providerUrl = providerUrl + "&access_token="+accessToken;
function sort(a, b) {
return b.signal - a.signal;

Просмотреть файл

@ -5170,6 +5170,7 @@ nsEditor::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
// Init selection
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
selCon->SetSelectionFlags(nsISelectionDisplay::DISPLAY_ALL);
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
// If the computed selection root isn't root content, we should set it
// as selection ancestor limit. However, if that is root element, it means

527
gfx/2d/Blur.cpp Normal file
Просмотреть файл

@ -0,0 +1,527 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla gfx.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "mozilla/gfx/Blur.h"
#include <algorithm>
#include <math.h>
#include <string.h>
#include "CheckedInt.h"
#include "mozilla/Util.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
using namespace std;
namespace mozilla {
namespace gfx {
/**
* Box blur involves looking at one pixel, and setting its value to the average
* of its neighbouring pixels.
* @param aInput The input buffer.
* @param aOutput The output buffer.
* @param aLeftLobe The number of pixels to blend on the left.
* @param aRightLobe The number of pixels to blend on the right.
* @param aWidth The number of columns in the buffers.
* @param aRows The number of rows in the buffers.
* @param aSkipRect An area to skip blurring in.
* XXX shouldn't we pass stride in separately here?
*/
static void
BoxBlurHorizontal(unsigned char* aInput,
unsigned char* aOutput,
int32_t aLeftLobe,
int32_t aRightLobe,
int32_t aWidth,
int32_t aRows,
const IntRect& aSkipRect)
{
MOZ_ASSERT(aWidth > 0);
int32_t boxSize = aLeftLobe + aRightLobe + 1;
bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
aWidth <= aSkipRect.XMost();
for (int32_t y = 0; y < aRows; y++) {
// Check whether the skip rect intersects this row. If the skip
// rect covers the whole surface in this row, we can avoid
// this row entirely (and any others along the skip rect).
bool inSkipRectY = y >= aSkipRect.y &&
y < aSkipRect.YMost();
if (inSkipRectY && skipRectCoversWholeRow) {
y = aSkipRect.YMost() - 1;
continue;
}
int32_t alphaSum = 0;
for (int32_t i = 0; i < boxSize; i++) {
int32_t pos = i - aLeftLobe;
// See assertion above; if aWidth is zero, then we would have no
// valid position to clamp to.
pos = max(pos, 0);
pos = min(pos, aWidth - 1);
alphaSum += aInput[aWidth * y + pos];
}
for (int32_t x = 0; x < aWidth; x++) {
// Check whether we are within the skip rect. If so, go
// to the next point outside the skip rect.
if (inSkipRectY && x >= aSkipRect.x &&
x < aSkipRect.XMost()) {
x = aSkipRect.XMost();
if (x >= aWidth)
break;
// Recalculate the neighbouring alpha values for
// our new point on the surface.
alphaSum = 0;
for (int32_t i = 0; i < boxSize; i++) {
int32_t pos = x + i - aLeftLobe;
// See assertion above; if aWidth is zero, then we would have no
// valid position to clamp to.
pos = max(pos, 0);
pos = min(pos, aWidth - 1);
alphaSum += aInput[aWidth * y + pos];
}
}
int32_t tmp = x - aLeftLobe;
int32_t last = max(tmp, 0);
int32_t next = min(tmp + boxSize, aWidth - 1);
aOutput[aWidth * y + x] = alphaSum / boxSize;
alphaSum += aInput[aWidth * y + next] -
aInput[aWidth * y + last];
}
}
}
/**
* Identical to BoxBlurHorizontal, except it blurs top and bottom instead of
* left and right.
* XXX shouldn't we pass stride in separately here?
*/
static void
BoxBlurVertical(unsigned char* aInput,
unsigned char* aOutput,
int32_t aTopLobe,
int32_t aBottomLobe,
int32_t aWidth,
int32_t aRows,
const IntRect& aSkipRect)
{
MOZ_ASSERT(aRows > 0);
int32_t boxSize = aTopLobe + aBottomLobe + 1;
bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
aRows <= aSkipRect.YMost();
for (int32_t x = 0; x < aWidth; x++) {
bool inSkipRectX = x >= aSkipRect.x &&
x < aSkipRect.XMost();
if (inSkipRectX && skipRectCoversWholeColumn) {
x = aSkipRect.XMost() - 1;
continue;
}
int32_t alphaSum = 0;
for (int32_t i = 0; i < boxSize; i++) {
int32_t pos = i - aTopLobe;
// See assertion above; if aRows is zero, then we would have no
// valid position to clamp to.
pos = max(pos, 0);
pos = min(pos, aRows - 1);
alphaSum += aInput[aWidth * pos + x];
}
for (int32_t y = 0; y < aRows; y++) {
if (inSkipRectX && y >= aSkipRect.y &&
y < aSkipRect.YMost()) {
y = aSkipRect.YMost();
if (y >= aRows)
break;
alphaSum = 0;
for (int32_t i = 0; i < boxSize; i++) {
int32_t pos = y + i - aTopLobe;
// See assertion above; if aRows is zero, then we would have no
// valid position to clamp to.
pos = max(pos, 0);
pos = min(pos, aRows - 1);
alphaSum += aInput[aWidth * pos + x];
}
}
int32_t tmp = y - aTopLobe;
int32_t last = max(tmp, 0);
int32_t next = min(tmp + boxSize, aRows - 1);
aOutput[aWidth * y + x] = alphaSum/boxSize;
alphaSum += aInput[aWidth * next + x] -
aInput[aWidth * last + x];
}
}
}
static void ComputeLobes(int32_t aRadius, int32_t aLobes[3][2])
{
int32_t major, minor, final;
/* See http://www.w3.org/TR/SVG/filters.html#feGaussianBlur for
* some notes about approximating the Gaussian blur with box-blurs.
* The comments below are in the terminology of that page.
*/
int32_t z = aRadius / 3;
switch (aRadius % 3) {
case 0:
// aRadius = z*3; choose d = 2*z + 1
major = minor = final = z;
break;
case 1:
// aRadius = z*3 + 1
// This is a tricky case since there is no value of d which will
// yield a radius of exactly aRadius. If d is odd, i.e. d=2*k + 1
// for some integer k, then the radius will be 3*k. If d is even,
// i.e. d=2*k, then the radius will be 3*k - 1.
// So we have to choose values that don't match the standard
// algorithm.
major = z + 1;
minor = final = z;
break;
case 2:
// aRadius = z*3 + 2; choose d = 2*z + 2
major = final = z + 1;
minor = z;
break;
default:
// Mathematical impossibility!
MOZ_ASSERT(false);
major = minor = final = 0;
}
MOZ_ASSERT(major + minor + final == aRadius);
aLobes[0][0] = major;
aLobes[0][1] = minor;
aLobes[1][0] = minor;
aLobes[1][1] = major;
aLobes[2][0] = final;
aLobes[2][1] = final;
}
static void
SpreadHorizontal(unsigned char* aInput,
unsigned char* aOutput,
int32_t aRadius,
int32_t aWidth,
int32_t aRows,
int32_t aStride,
const IntRect& aSkipRect)
{
if (aRadius == 0) {
memcpy(aOutput, aInput, aStride * aRows);
return;
}
bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
aWidth <= aSkipRect.XMost();
for (int32_t y = 0; y < aRows; y++) {
// Check whether the skip rect intersects this row. If the skip
// rect covers the whole surface in this row, we can avoid
// this row entirely (and any others along the skip rect).
bool inSkipRectY = y >= aSkipRect.y &&
y < aSkipRect.YMost();
if (inSkipRectY && skipRectCoversWholeRow) {
y = aSkipRect.YMost() - 1;
continue;
}
for (int32_t x = 0; x < aWidth; x++) {
// Check whether we are within the skip rect. If so, go
// to the next point outside the skip rect.
if (inSkipRectY && x >= aSkipRect.x &&
x < aSkipRect.XMost()) {
x = aSkipRect.XMost();
if (x >= aWidth)
break;
}
int32_t sMin = max(x - aRadius, 0);
int32_t sMax = min(x + aRadius, aWidth - 1);
int32_t v = 0;
for (int32_t s = sMin; s <= sMax; ++s) {
v = max<int32_t>(v, aInput[aStride * y + s]);
}
aOutput[aStride * y + x] = v;
}
}
}
static void
SpreadVertical(unsigned char* aInput,
unsigned char* aOutput,
int32_t aRadius,
int32_t aWidth,
int32_t aRows,
int32_t aStride,
const IntRect& aSkipRect)
{
if (aRadius == 0) {
memcpy(aOutput, aInput, aStride * aRows);
return;
}
bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
aRows <= aSkipRect.YMost();
for (int32_t x = 0; x < aWidth; x++) {
bool inSkipRectX = x >= aSkipRect.x &&
x < aSkipRect.XMost();
if (inSkipRectX && skipRectCoversWholeColumn) {
x = aSkipRect.XMost() - 1;
continue;
}
for (int32_t y = 0; y < aRows; y++) {
// Check whether we are within the skip rect. If so, go
// to the next point outside the skip rect.
if (inSkipRectX && y >= aSkipRect.y &&
y < aSkipRect.YMost()) {
y = aSkipRect.YMost();
if (y >= aRows)
break;
}
int32_t sMin = max(y - aRadius, 0);
int32_t sMax = min(y + aRadius, aRows - 1);
int32_t v = 0;
for (int32_t s = sMin; s <= sMax; ++s) {
v = max<int32_t>(v, aInput[aStride * s + x]);
}
aOutput[aStride * y + x] = v;
}
}
}
static CheckedInt<int32_t>
RoundUpToMultipleOf4(int32_t aVal)
{
CheckedInt<int32_t> val(aVal);
val += 3;
val /= 4;
val *= 4;
return val;
}
AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
const IntSize& aSpreadRadius,
const IntSize& aBlurRadius,
const Rect* aDirtyRect,
const Rect* aSkipRect)
: mSpreadRadius(aSpreadRadius),
mBlurRadius(aBlurRadius),
mData(NULL)
{
Rect rect(aRect);
rect.Inflate(Size(aBlurRadius + aSpreadRadius));
rect.RoundOut();
if (aDirtyRect) {
// If we get passed a dirty rect from layout, we can minimize the
// shadow size and make painting faster.
mHasDirtyRect = true;
mDirtyRect = *aDirtyRect;
Rect requiredBlurArea = mDirtyRect.Intersect(rect);
requiredBlurArea.Inflate(Size(aBlurRadius + aSpreadRadius));
rect = requiredBlurArea.Intersect(rect);
} else {
mHasDirtyRect = false;
}
if (rect.IsEmpty()) {
return;
}
if (aSkipRect) {
// If we get passed a skip rect, we can lower the amount of
// blurring/spreading we need to do. We convert it to IntRect to avoid
// expensive int<->float conversions if we were to use Rect instead.
Rect skipRect = *aSkipRect;
skipRect.RoundIn();
skipRect.Deflate(Size(aBlurRadius + aSpreadRadius));
mSkipRect = IntRect(skipRect.x, skipRect.y, skipRect.width, skipRect.height);
IntRect shadowIntRect(rect.x, rect.y, rect.width, rect.height);
mSkipRect.IntersectRect(mSkipRect, shadowIntRect);
if (mSkipRect.IsEqualInterior(shadowIntRect))
return;
mSkipRect -= shadowIntRect.TopLeft();
} else {
mSkipRect = IntRect(0, 0, 0, 0);
}
mRect = IntRect(rect.x, rect.y, rect.width, rect.height);
CheckedInt<int32_t> stride = RoundUpToMultipleOf4(mRect.width);
if (stride.valid()) {
mStride = stride.value();
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height *
sizeof(unsigned char);
if (size.valid()) {
mData = static_cast<unsigned char*>(malloc(size.value()));
memset(mData, 0, size.value());
}
}
}
AlphaBoxBlur::~AlphaBoxBlur()
{
free(mData);
}
unsigned char*
AlphaBoxBlur::GetData()
{
return mData;
}
IntSize
AlphaBoxBlur::GetSize()
{
IntSize size(mRect.width, mRect.height);
return size;
}
int32_t
AlphaBoxBlur::GetStride()
{
return mStride;
}
IntRect
AlphaBoxBlur::GetRect()
{
return mRect;
}
Rect*
AlphaBoxBlur::GetDirtyRect()
{
if (mHasDirtyRect) {
return &mDirtyRect;
}
return NULL;
}
void
AlphaBoxBlur::Blur()
{
if (!mData) {
return;
}
// no need to do all this if not blurring or spreading
if (mBlurRadius != IntSize(0,0) || mSpreadRadius != IntSize(0,0)) {
int32_t stride = GetStride();
// No need to use CheckedInt here - we have validated it in the constructor.
size_t szB = stride * GetSize().height * sizeof(unsigned char);
unsigned char* tmpData = static_cast<unsigned char*>(malloc(szB));
if (!tmpData)
return; // OOM
memset(tmpData, 0, szB);
if (mSpreadRadius.width > 0 || mSpreadRadius.height > 0) {
SpreadHorizontal(mData, tmpData, mSpreadRadius.width, GetSize().width, GetSize().height, stride, mSkipRect);
SpreadVertical(tmpData, mData, mSpreadRadius.height, GetSize().width, GetSize().height, stride, mSkipRect);
}
if (mBlurRadius.width > 0) {
int32_t lobes[3][2];
ComputeLobes(mBlurRadius.width, lobes);
BoxBlurHorizontal(mData, tmpData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
BoxBlurHorizontal(tmpData, mData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
BoxBlurHorizontal(mData, tmpData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
} else {
memcpy(tmpData, mData, stride * GetSize().height);
}
if (mBlurRadius.height > 0) {
int32_t lobes[3][2];
ComputeLobes(mBlurRadius.height, lobes);
BoxBlurVertical(tmpData, mData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
BoxBlurVertical(mData, tmpData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
BoxBlurVertical(tmpData, mData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
} else {
memcpy(mData, tmpData, stride * GetSize().height);
}
free(tmpData);
}
}
/**
* Compute the box blur size (which we're calling the blur radius) from
* the standard deviation.
*
* Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
* approximating a Gaussian using box blurs. This yields quite a good
* approximation for a Gaussian. Then we multiply this by 1.5 since our
* code wants the radius of the entire triple-box-blur kernel instead of
* the diameter of an individual box blur. For more details, see:
* http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
* https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
*/
static const Float GAUSSIAN_SCALE_FACTOR = (3 * sqrt(2 * M_PI) / 4) * 1.5;
IntSize
AlphaBoxBlur::CalculateBlurRadius(const Point& aStd)
{
IntSize size(static_cast<int32_t>(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5)),
static_cast<int32_t>(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5)));
return size;
}
}
}

185
gfx/2d/Blur.h Normal file
Просмотреть файл

@ -0,0 +1,185 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla gfx.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_BLUR_H_
#define MOZILLA_GFX_BLUR_H_
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/Point.h"
namespace mozilla {
namespace gfx {
/**
* Implementation of a triple box blur approximation of a Gaussian blur.
*
* A Gaussian blur is good for blurring because, when done independently
* in the horizontal and vertical directions, it matches the result that
* would be obtained using a different (rotated) set of axes. A triple
* box blur is a very close approximation of a Gaussian.
*
* Creates an 8-bit alpha channel context for callers to draw in,
* spreads the contents of that context, and blurs the contents.
*
* A spread N makes each output pixel the maximum value of all source
* pixels within a square of side length 2N+1 centered on the output pixel.
*
* A temporary surface is created in the Init function. The caller then draws
* any desired content onto the context acquired through GetContext, and lastly
* calls Paint to apply the blurred content as an alpha mask.
*/
class AlphaBoxBlur
{
public:
/** Constructs a box blur and initializes the backing surface.
*
* @param aRect The coordinates of the surface to create in device units.
*
* @param aBlurRadius The blur radius in pixels. This is the radius of the
* entire (triple) kernel function. Each individual box blur has radius
* approximately 1/3 this value, or diameter approximately 2/3 this value.
* This parameter should nearly always be computed using CalculateBlurRadius,
* below.
*
* @param aDirtyRect A pointer to a dirty rect, measured in device units, if
* available. This will be used for optimizing the blur operation. It is
* safe to pass NULL here.
*
* @param aSkipRect A pointer to a rect, measured in device units, that
* represents an area where blurring is unnecessary and shouldn't be done for
* speed reasons. It is safe to pass NULL here.
*/
AlphaBoxBlur(const Rect& aRect,
const IntSize& aSpreadRadius,
const IntSize& aBlurRadius,
const Rect* aDirtyRect,
const Rect* aSkipRect);
~AlphaBoxBlur();
/**
* Return the pointer to memory allocated by the constructor for the 8-bit
* alpha surface you need to be blurred. After you draw to this surface, call
* Blur(), below, to have its contents blurred.
*/
unsigned char* GetData();
/**
* Return the size, in pixels, of the 8-bit alpha surface backed by the
* pointer returned by GetData().
*/
IntSize GetSize();
/**
* Return the stride, in bytes, of the 8-bit alpha surface backed by the
* pointer returned by GetData().
*/
int32_t GetStride();
/**
* Returns the device-space rectangle the 8-bit alpha surface covers.
*/
IntRect GetRect();
/**
* Return a pointer to a dirty rect, as passed in to the constructor, or NULL
* if none was passed in.
*/
Rect* GetDirtyRect();
/**
* Perform the blur in-place on the surface backed by the pointer returned by
* GetData().
*/
void Blur();
/**
* Calculates a blur radius that, when used with box blur, approximates a
* Gaussian blur with the given standard deviation. The result of this
* function should be used as the aBlurRadius parameter to AlphaBoxBlur's
* constructor, above.
*/
static IntSize CalculateBlurRadius(const Point& aStandardDeviation);
private:
/**
* A rect indicating the area where blurring is unnecessary, and the blur
* algorithm should skip over it.
*/
IntRect mSkipRect;
/**
* The device-space rectangle the the backing 8-bit alpha surface covers.
*/
IntRect mRect;
/**
* A copy of the dirty rect passed to the constructor. This will only be valid if
* mHasDirtyRect is true.
*/
Rect mDirtyRect;
/**
* The spread radius, in pixels.
*/
IntSize mSpreadRadius;
/**
* The blur radius, in pixels.
*/
IntSize mBlurRadius;
/**
* A pointer to the backing 8-bit alpha surface.
*/
unsigned char* mData;
/**
* The stride of the data contained in mData.
*/
int32_t mStride;
/**
* Whether mDirtyRect contains valid data.
*/
bool mHasDirtyRect;
};
}
}
#endif /* MOZILLA_GFX_BLUR_H_ */

Просмотреть файл

@ -56,6 +56,7 @@ EXPORTS_mozilla/gfx = \
BaseMargin.h \
BaseRect.h \
BaseSize.h \
Blur.h \
PathHelpers.h \
Point.h \
Matrix.h \
@ -68,6 +69,7 @@ CPPSRCS = \
Matrix.cpp \
DrawTargetCairo.cpp \
SourceSurfaceCairo.cpp \
Blur.cpp \
$(NULL)

Просмотреть файл

@ -48,7 +48,7 @@ ifdef MOZ_TREE_CAIRO
DIRS = cairo
endif
DIRS += 2d ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
DIRS += 2d ycbcr angle src qcms gl layers harfbuzz/src ots/src thebes ipc
ifeq (,$(filter-out cocoa android windows,$(MOZ_WIDGET_TOOLKIT)))
DIRS += skia

Просмотреть файл

@ -1,6 +1,6 @@
This is the ANGLE project, from http://code.google.com/p/angleproject/
Current revision: r809
Current revision: r885
== Applied local patches ==

Просмотреть файл

@ -1,5 +1,5 @@
# HG changeset patch
# Parent b5604c321da4e3b5d6b0a940d18022a827061579
# Parent d9b887da80f5bc18854fb3e5e43637c18d2a25ae
diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
--- a/gfx/angle/src/libGLESv2/Texture.cpp
+++ b/gfx/angle/src/libGLESv2/Texture.cpp

Просмотреть файл

@ -1,5 +1,5 @@
# HG changeset patch
# Parent 0239f15c7212413b5cffe66aee9ae5a4feb28f16
# Parent eae39c479485f310e937d8550afc6596aec20159
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in

Просмотреть файл

@ -1,5 +1,5 @@
# HG changeset patch
# Parent fecc64a6df53a9056b21958affad38c80ca38496
# Parent 85ffde53712cab3c217bbbf0c1ec9b7ec2ae8ea6
diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
--- a/gfx/angle/Makefile.in
@ -7,7 +7,7 @@ diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
@@ -127,16 +127,18 @@ CSRCS = \
$(NULL)
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD
DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
#these defines are from ANGLE's build_angle.gyp
DEFINES += -DANGLE_DISABLE_TRACE
@ -27,13 +27,13 @@ diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -3,16 +3,17 @@ This is the ANGLE project, from http://c
Current revision: r774
Current revision: r885
== Applied local patches ==
In this order:
angle-renaming.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-instrinsic-msvc2005.patch - work around a MSVC 2005 compile error
angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
angle-limit-identifiers-to-250-chars.patch - see bug 675625
+ angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
@ -44,20 +44,6 @@ diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
1. Unapply patches
2. Apply diff with new ANGLE version
3. Reapply patches.
diff --git a/gfx/angle/angle-limit-identifiers-to-250-chars.patch b/gfx/angle/angle-limit-identifiers-to-250-chars.patch
--- a/gfx/angle/angle-limit-identifiers-to-250-chars.patch
+++ b/gfx/angle/angle-limit-identifiers-to-250-chars.patch
@@ -1,8 +1,10 @@
+# HG changeset patch
+# Parent f9415c10c3ebd27856500cca7a0ee0f28a16f53c
diff --git a/gfx/angle/src/compiler/preprocessor/scanner.h b/gfx/angle/src/compiler/preprocessor/scanner.h
--- a/gfx/angle/src/compiler/preprocessor/scanner.h
+++ b/gfx/angle/src/compiler/preprocessor/scanner.h
@@ -44,17 +44,19 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
//
// scanner.h
//
diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
--- a/gfx/angle/src/compiler/preprocessor/atom.c
+++ b/gfx/angle/src/compiler/preprocessor/atom.c

Просмотреть файл

@ -0,0 +1,202 @@
Name
ANGLE_texture_usage
Name Strings
GL_ANGLE_texture_usage
Contributors
Nicolas Capens, TransGaming
Daniel Koch, TransGaming
Contact
Daniel Koch, TransGaming (daniel 'at' transgaming.com)
Status
Complete
Version
Last Modified Date: November 10, 2011
Version: 2
Number
TBD
Dependencies
This extension is written against the OpenGL ES 2.0 Specification.
Overview
In some implementations it is advantageous to know the expected
usage of a texture before the backing storage for it is allocated.
This can help to inform the implementation's choice of format
and type of memory used for the allocation. If the usage is not
known in advance, the implementation essentially has to make a
guess as to how it will be used. If it is later proven wrong,
it may need to perform costly re-allocations and/or reformatting
of the texture data, resulting in reduced performance.
This extension adds a texture usage flag that is specified via
the TEXTURE_USAGE_ANGLE TexParameter. This can be used to
indicate that the application knows that this texture will be
used for rendering.
IP Status
No known IP claims.
New Procedures and Functions
None
New Tokens
Accepted as a value for <pname> for the TexParameter{if} and
TexParameter{if}v commands and for the <value> parameter of
GetTexParameter{if}v:
TEXTURE_USAGE_ANGLE 0x93A2
Accepted as a value to <param> for the TexParameter{if} and
to <params> for the TexParameter{if}v commands with a <pname> of
TEXTURE_USAGE_ANGLE; returned as possible values for <data> when
GetTexParameter{if}v is queried with a <value> of TEXTURE_USAGE_ANGLE:
NONE 0x0000
FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
None
Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
Add a new row to Table 3.10 (Texture parameters and their values):
Name | Type | Legal Values
------------------------------------------------------------
TEXTURE_USAGE_ANGLE | enum | NONE, FRAMEBUFFER_ATTACHMENT_ANGLE
Add a new section 3.7.x (Texture Usage) before section 3.7.12 and
renumber the subsequent sections:
"3.7.x Texture Usage
Texture usage can be specified via the TEXTURE_USAGE_ANGLE value
for the <pname> argument to TexParameter{if}[v]. In order to take effect,
the texture usage must be specified before the texture contents are
defined either via TexImage2D or TexStorage2DEXT.
The usage values can impact the layout and type of memory used for the
texture data. Specifying incorrect usage values may result in reduced
functionality and/or significantly degraded performance.
Possible values for <params> when <pname> is TEXTURE_USAGE_ANGLE are:
NONE - the default. No particular usage has been specified and it is
up to the implementation to determine the usage of the texture.
Leaving the usage unspecified means that the implementation may
have to reallocate the texture data as the texture is used in
various ways.
FRAMEBUFFER_ATTACHMENT_ANGLE - this texture will be attached to a
framebuffer object and used as a desination for rendering or blits."
Modify section 3.7.12 (Texture State) and place the last 3 sentences
with the following:
"Next, there are the three sets of texture properties; each consists of
the selected minification and magnification filters, the wrap modes for
<s> and <t>, and the usage flags. In the initial state, the value assigned
to TEXTURE_MIN_FILTER is NEAREST_MIPMAP_LINEAR, and the value for
TEXTURE_MAG_FILTER is LINEAR. <s> and <t> wrap modes are both set to
REPEAT. The initial value for TEXTURE_USAGE_ANGLE is NONE."
Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Framebuffer)
None
Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special
Functions):
None
Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and
State Requests)
None
Dependencies on EXT_texture_storage
If EXT_texture_storage is not supported, omit any references to
TexStorage2DEXT.
Errors
If TexParameter{if} or TexParamter{if}v is called with a <pname>
of TEXTURE_USAGE_ANGLE and the value of <param> or <params> is not
NONE or FRAMEBUFFER_ATTACHMENT_ANGLE the error INVALID_VALUE is
generated.
Usage Example
/* create and bind texture */
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
/* specify texture parameters */
glTexParameteri(GL_TEXTURE_2D, GL_*, ...); /* as before */
/* specify that we'll be rendering to the texture */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
glTexStorage2DEXT(GL_TEXTURE_2D, levels, ...); // Allocation
for(int level = 0; level < levels; ++level)
glTexSubImage2D(GL_TEXTURE_2D, level, ...); // Initialisation
Issues
1. Should there be a dynamic usage value?
DISCUSSION: We could accept a dynamic flag to indicate that a texture will
be updated frequently. We could map this to D3D9 dynamic textures. This would
allow us to avoid creating temporary surfaces when updating the texture.
However renderable textures cannot be dynamic in D3D9, which eliminates the
primary use case for this. Furthermore, the memory usage of dynamic textures
typically increases threefold when you lock it.
2. Should the texture usage be an enum or a bitfield?
UNRESOLVED. Using a bitfield would allow combination of values to be specified.
On the other hand, if combinations are really required, additional <pnames>
could be added as necessary. Querying a bitfield via the GetTexParameter command
feels a bit odd.
3. What should happen if TEXTURE_USAGE_ANGLE is set/changed after the texture
contents have been specified?
RESOLVED: It will have no effect. However, if the texture is redefined (for
example by TexImage2D) the new allocation will use the updated usage.
GetTexParameter is used to query the value of the TEXTURE_USAGE_ANGLE
state that was last set by TexParameter for the currently bound texture, or
the default value if it has never been set. There is no way to determine the
usage that was in effect at the time the texture was defined.
Revision History
Rev. Date Author Changes
---- ----------- --------- ----------------------------------------
1 10 Nov 2011 dgkoch Initial revision
2 10 Nov 2011 dgkoch Add overview

Просмотреть файл

@ -0,0 +1,169 @@
Name
EXT_create_context_robustness
Name Strings
EGL_EXT_create_context_robustness
Contributors
Daniel Koch, TransGaming
Contributors to EGL_KHR_create_context
Contact
Greg Roth (groth 'at' nvidia.com)
Status
Complete.
Version
Version 3, 2011/10/31
Number
TBD
Dependencies
Requires EGL 1.4
Written against the EGL 1.4 specification.
An OpenGL implementation supporting GL_ARB_robustness, an OpenGL ES
implementation supporting GL_EXT_robustness, or an implementation
supporting equivalent functionality is required.
Overview
This extension allows creating an OpenGL or OpenGL ES context
supporting robust buffer access behavior and a specified graphics
reset notification behavior.
New Procedures and Functions
None
New Tokens
Accepted as an attribute name in the <*attrib_list> argument to
eglCreateContext:
EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
Accepted as an attribute value for EGL_CONTEXT_RESET_NOTIFICATION_-
STRATEGY_EXT in the <*attrib_list> argument to eglCreateContext:
EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
Additions to the EGL 1.4 Specification
Replace section 3.7.1 "Creating Rendering Contexts" from the
fifth paragraph through the seventh paragraph:
<attrib_list> specifies a list of attributes for the context. The
list has the same structure as described for eglChooseConfig. If an
attribute is not specified in <attrib_list>, then the default value
specified below is used instead. <attrib_list> may be NULL or empty
(first attribute is EGL_NONE), in which case attributes assume their
default values as described below. Most attributes are only meaningful
for specific client APIs, and will generate an EGL_BAD_ATTRIBUTE
error when specified to create for another client API context.
Context Versions
----------------
EGL_CONTEXT_CLIENT_VERSION determines which version of an OpenGL ES
context to create. This attribute may only be specified when creating
an OpenGL ES context (e.g. when the current rendering API is
EGL_OPENGL_ES_API). An attribute value of 1 specifies creation of an
OpenGL ES 1.x context. An attribute value of 2 specifies creation of an
Open GL ES 2.x context. The default value for EGL_CONTEXT_CLIENT_VERSION
is 1.
Context Robust Access
-------------
EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT indicates whether <robust buffer
access> should be enabled for the OpenGL ES context. Robust buffer
access is defined in the GL_EXT_robustness extension specification,
and the resulting context must support GL_EXT_robustness and robust
buffer access as described therein. The default value of
EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT is EGL_FALSE.
Context Reset Notification
--------------------------
The attribute name EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_-
EXT specifies the <reset notification behavior> of the rendering
context. This attribute is only meaningful for OpenGL ES contexts,
and specifying it for other types of contexts will generate an
EGL_BAD_ATTRIBUTE error.
Reset notification behavior is defined in the GL_EXT_robustness
extension for OpenGL ES, and the resulting context must support
GL_EXT_robustness and the specified reset strategy. The attribute
value may be either EGL_NO_RESET_NOTIFICATION_EXT or EGL_LOSE_-
CONTEXT_ON_RESET_EXT, which respectively result in disabling
delivery of reset notifications or the loss of all context state
upon reset notification as described by the GL_EXT_robustness. The
default value for EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT
is EGL_NO_RESET_NOTIFICATION_EXT.
Add to the eglCreateContext context creation errors:
* If <config> does not support a client API context compatible
with the requested context flags and context reset notification
behavior (for client API types where these attributes are
supported), then an EGL_BAD_CONFIG error is generated.
* If the reset notification behavior of <share_context> and the
newly created context are different then an EGL_BAD_MATCH error is
generated.
Errors
EGL_BAD_CONFIG is generated if EGL_CONTEXT_OPENGL_ROBUST_ACCESS_-
EXT is set to EGL_TRUE and no GL context supporting the GL_EXT_-
robustness extension and robust access as described therein can be
created.
EGL_BAD_CONFIG is generated if no GL context supporting the
GL_EXT_robustness extension and the specified reset notification
behavior (the value of attribute EGL_CONTEXT_RESET_NOTIFICATION_-
STRATEGY_EXT) can be created.
BAD_MATCH is generated if the reset notification behavior of
<share_context> does not match the reset notification behavior of
the context being created.
New State
None
Conformance Tests
TBD
Sample Code
TBD
Issues
None
Revision History
Rev. Date Author Changes
---- ------------ --------- ----------------------------------------
3 31 Oct 2011 groth Reverted to attribute for robust access. Now it's a
companion to rather than subset of KHR_create_context
2 11 Oct 2011 groth Merged ANGLE and NV extensions.
1 15 July 2011 groth Initial version

Просмотреть файл

@ -0,0 +1,365 @@
Name
EXT_robustness
Name Strings
GL_EXT_robustness
Contributors
Daniel Koch, TransGaming
Nicolas Capens, TransGaming
Contributors to ARB_robustness
Contact
Greg Roth, NVIDIA (groth 'at' nvidia.com)
Status
Complete.
Version
Version 3, 2011/10/31
Number
TBD
Dependencies
This extension is written against the OpenGL ES 2.0 Specification
but can apply to OpenGL ES 1.1 and up.
EGL_EXT_create_context_robustness is used to determine if a context
implementing this extension supports robust buffer access, and if it
supports reset notification.
Overview
Several recent trends in how OpenGL integrates into modern computer
systems have created new requirements for robustness and security
for OpenGL rendering contexts.
Additionally GPU architectures now support hardware fault detection;
for example, video memory supporting ECC (error correcting codes)
and error detection. OpenGL contexts should be capable of recovering
from hardware faults such as uncorrectable memory errors. Along with
recovery from such hardware faults, the recovery mechanism can
also allow recovery from video memory access exceptions and system
software failures. System software failures can be due to device
changes or driver failures.
OpenGL queries that that return (write) some number of bytes to a
buffer indicated by a pointer parameter introduce risk of buffer
overflows that might be exploitable by malware. To address this,
queries with return value sizes that are not expressed directly by
the parameters to the query itself are given additional API
functions with an additional parameter that specifies the number of
bytes in the buffer and never writing bytes beyond that limit. This
is particularly useful for multi-threaded usage of OpenGL contexts
in a "share group" where one context can change objects in ways that
can cause buffer overflows for another context's OpenGL queries.
The original ARB_vertex_buffer_object extension includes an issue
that explicitly states program termination is allowed when
out-of-bounds vertex buffer object fetches occur. Modern graphics
hardware is capable well-defined behavior in the case of out-of-
bounds vertex buffer object fetches. Older hardware may require
extra checks to enforce well-defined (and termination free)
behavior, but this expense is warranted when processing potentially
untrusted content.
The intent of this extension is to address some specific robustness
goals:
* For all existing OpenGL queries, provide additional "safe" APIs
that limit data written to user pointers to a buffer size in
bytes that is an explicit additional parameter of the query.
* Provide a mechanism for an OpenGL application to learn about
graphics resets that affect the context. When a graphics reset
occurs, the OpenGL context becomes unusable and the application
must create a new context to continue operation. Detecting a
graphics reset happens through an inexpensive query.
* Provide an enable to guarantee that out-of-bounds buffer object
accesses by the GPU will have deterministic behavior and preclude
application instability or termination due to an incorrect buffer
access. Such accesses include vertex buffer fetches of
attributes and indices, and indexed reads of uniforms or
parameters from buffers.
New Procedures and Functions
enum GetGraphicsResetStatusEXT();
void ReadnPixelsEXT(int x, int y, sizei width, sizei height,
enum format, enum type, sizei bufSize,
void *data);
void GetnUniformfvEXT(uint program, int location, sizei bufSize,
float *params);
void GetnUniformivEXT(uint program, int location, sizei bufSize,
int *params);
New Tokens
Returned by GetGraphicsResetStatusEXT:
NO_ERROR 0x0000
GUILTY_CONTEXT_RESET_EXT 0x8253
INNOCENT_CONTEXT_RESET_EXT 0x8254
UNKNOWN_CONTEXT_RESET_EXT 0x8255
Accepted by the <value> parameter of GetBooleanv, GetIntegerv,
and GetFloatv:
CONTEXT_ROBUST_ACCESS_EXT 0x90F3
RESET_NOTIFICATION_STRATEGY_EXT 0x8256
Returned by GetIntegerv and related simple queries when <value> is
RESET_NOTIFICATION_STRATEGY_EXT :
LOSE_CONTEXT_ON_RESET_EXT 0x8252
NO_RESET_NOTIFICATION_EXT 0x8261
Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
Add a new subsection after 2.5 "GL Errors" and renumber subsequent
sections accordingly.
2.6 "Graphics Reset Recovery"
Certain events can result in a reset of the GL context. Such a reset
causes all context state to be lost. Recovery from such events
requires recreation of all objects in the affected context. The
current status of the graphics reset state is returned by
enum GetGraphicsResetStatusEXT();
The symbolic constant returned indicates if the GL context has been
in a reset state at any point since the last call to
GetGraphicsResetStatusEXT. NO_ERROR indicates that the GL context
has not been in a reset state since the last call.
GUILTY_CONTEXT_RESET_EXT indicates that a reset has been detected
that is attributable to the current GL context.
INNOCENT_CONTEXT_RESET_EXT indicates a reset has been detected that
is not attributable to the current GL context.
UNKNOWN_CONTEXT_RESET_EXT indicates a detected graphics reset whose
cause is unknown.
If a reset status other than NO_ERROR is returned and subsequent
calls return NO_ERROR, the context reset was encountered and
completed. If a reset status is repeatedly returned, the context may
be in the process of resetting.
Reset notification behavior is determined at context creation time,
and may be queried by calling GetIntegerv with the symbolic constant
RESET_NOTIFICATION_STRATEGY_EXT.
If the reset notification behavior is NO_RESET_NOTIFICATION_EXT,
then the implementation will never deliver notification of reset
events, and GetGraphicsResetStatusEXT will always return
NO_ERROR[fn1].
[fn1: In this case it is recommended that implementations should
not allow loss of context state no matter what events occur.
However, this is only a recommendation, and cannot be relied
upon by applications.]
If the behavior is LOSE_CONTEXT_ON_RESET_EXT, a graphics reset will
result in the loss of all context state, requiring the recreation of
all associated objects. In this case GetGraphicsResetStatusEXT may
return any of the values described above.
If a graphics reset notification occurs in a context, a notification
must also occur in all other contexts which share objects with that
context[fn2].
[fn2: The values returned by GetGraphicsResetStatusEXT in the
different contexts may differ.]
Add to Section 2.8 "Vertex Arrays" before subsection "Transferring
Array Elements"
Robust buffer access is enabled by creating a context with robust
access enabled through the window system binding APIs. When enabled,
indices within the vertex array that lie outside the arrays defined
for enabled attributes result in undefined values for the
corresponding attributes, but cannot result in application failure.
Robust buffer access behavior may be queried by calling GetIntegerv
with the symbolic constant CONTEXT_ROBUST_ACCESS_EXT.
Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
Modify section 4.3.1 "Reading Pixels"
Pixels are read using
void ReadPixels(int x, int y, sizei width, sizei height,
enum format, enum type, void *data);
void ReadnPixelsEXT(int x, int y, sizei width, sizei height,
enum format, enum type, sizei bufSize,
void *data);
Add to the description of ReadPixels:
ReadnPixelsEXT behaves identically to ReadPixels except that it does
not write more than <bufSize> bytes into <data>. If the buffer size
required to fill all the requested data is greater than <bufSize> an
INVALID_OPERATION error is generated and <data> is not altered.
Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special
Functions):
None
Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and
State Requests)
Modify Section 6.1.8 "Shader and Program Queries"
The commands
void GetUniformfv(uint program, int location, float *params);
void GetnUniformfvEXT(uint program, int location, sizei bufSize,
float *params);
void GetUniformiv(uint program, int location, int *params);
void GetnUniformivEXT(uint program, int location, sizei bufSize,
int *params);
return the value or values of the uniform at location <location>
for program object <program> in the array <params>. Calling
GetnUniformfvEXT or GetnUniformivEXT ensures that no more than
<bufSize> bytes are written into <params>. If the buffer size
required to fill all the requested data is greater than <bufSize> an
INVALID_OPERATION error is generated and <params> is not altered.
...
Additions to The OpenGL ES Shading Language Specification, Version 1.
Append to the third paragraph of section 4.1.9 "Arrays"
If robust buffer access is enabled via the OpenGL ES API, such
indexing must not result in abnormal program termination. The
results are still undefined, but implementations are encouraged to
produce zero values for such accesses.
Interactions with EGL_EXT_create_context_robustness
If the EGL window-system binding API is used to create a context,
the EGL_EXT_create_context_robustness extension is supported, and
the attribute EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT is set to
EGL_TRUE when eglCreateContext is called, the resulting context will
perform robust buffer access as described above in section 2.8, and
the CONTEXT_ROBUST_ACCESS_EXT query will return GL_TRUE as described
above in section 6.1.5.
If the EGL window-system binding API is used to create a context and
the EGL_EXT_create_context_robustness extension is supported, then
the value of attribute EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT
determines the reset notification behavior and the value of
RESET_NOTIFICATION_STRATEGY_EXT, as described in section 2.6.
Errors
ReadnPixelsEXT, GetnUniformfvEXT, and GetnUniformivEXT share all the
errors of their unsized buffer query counterparts with the addition
that INVALID_OPERATION is generated if the buffer size required to
fill all the requested data is greater than <bufSize>.
New Implementation Dependent State
Get Value Type Get Command Minimum Value Description Sec. Attribute
--------- ---- ----------- ------------- --------------------------- ----- ---------
CONTEXT_ROBUST_ACCESS_EXT B GetIntegerv - Robust access enabled 6.1.5 -
RESET_NOTIFICATION_STRATEGY_EXT Z_2 GetIntegerv See sec. 2.6 Reset notification behavior 2.6 -
Issues
1. What should this extension be called?
RESOLVED: EXT_robustness
Since this is intended to be a version of ARB_robustness for
OpenGL ES, it should be named accordingly.
2. How does this extension differ from Desktop GL's ARB_robustness?
RESOLVED: Because EGL_EXT_create_context_robustness uses a
separate attribute to enable robust buffer access, a
corresponding query is added here.
3. Should we provide a context creation mechanism to enable this extension?
RESOLVED. Yes.
Currently, EGL_EXT_create_context_robustness provides this
mechanism via two unique attributes. These attributes differ
from those specified by KHR_create_context to allow for
differences in what functionality those attributes define.
4. What can cause a graphics reset?
Either user or implementor errors may result in a graphics reset.
If the application attempts to perform a rendering that takes too long
whether due to an infinite loop in a shader or even just a rendering
operation that takes too long on the given hardware. Implementation
errors may produce badly formed hardware commands. Memory access errors
may result from user or implementor mistakes. On some systems, power
management events such as system sleep, screen saver activation, or
pre-emption may also context resets to occur. Any of these events may
result in a graphics reset event that will be detectable by the
mechanism described in this extension.
5. How should the application react to a reset context event?
RESOLVED: For this extension, the application is expected to query
the reset status until NO_ERROR is returned. If a reset is encountered,
at least one *RESET* status will be returned. Once NO_ERROR is again
encountered, the application can safely destroy the old context and
create a new one.
After a reset event, apps should not use a context for any purpose
other than determining its reset status, and then destroying it. If a
context receives a reset event, all other contexts in its share group
will also receive reset events, and should be destroyed and
recreated.
Apps should be cautious in interpreting the GUILTY and INNOCENT reset
statuses. These are guidelines to the immediate cause of a reset, but
not guarantees of the ultimate cause.
6. If a graphics reset occurs in a shared context, what happens in
shared contexts?
RESOLVED: A reset in one context will result in a reset in all other
contexts in its share group.
7. How can an application query for robust buffer access support,
since this is now determined at context creation time?
RESOLVED. The application can query the value of ROBUST_ACCESS_EXT
using GetIntegerv. If true, this functionality is enabled.
8. How is the reset notification behavior controlled?
RESOLVED: Reset notification behavior is determined at context
creation time using EGL/GLX/WGL/etc. mechanisms. In order that shared
objects be handled predictably, a context cannot share with
another context unless both have the same reset notification
behavior.
Revision History
Rev. Date Author Changes
---- ------------ --------- ----------------------------------------
3 31 Oct 2011 groth Reverted to attribute for robust access. Now it's a
companion to rather than subset of KHR_create_context
2 11 Oct 2011 groth Merged ANGLE and NV extensions.
Convert to using flag to indicate robust access.
1 15 July 2011 groth Initial version

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -318,6 +318,14 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif
#ifndef EGL_EXT_create_context_robustness
#define EGL_EXT_create_context_robustness 1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
#endif
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
#ifndef EGL_NV_system_time
#define EGL_NV_system_time 1

Просмотреть файл

@ -222,6 +222,12 @@ typedef void* GLeglImageOES;
#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
#endif
/* GL_ANGLE_texture_usage */
#ifndef GL_ANGLE_texture_usage
#define GL_TEXTURE_USAGE_ANGLE 0x93A2
#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
#endif
/*------------------------------------------------------------------------*
* APPLE extension tokens
*------------------------------------------------------------------------*/
@ -325,6 +331,42 @@ typedef void* GLeglImageOES;
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
#endif
/* GL_EXT_robustness */
#ifndef GL_EXT_robustness
#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
#endif
/* GL_EXT_texture_storage */
#ifndef GL_EXT_texture_storage
#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
#define GL_ALPHA8_EXT 0x803C
#define GL_LUMINANCE8_EXT 0x8040
#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
/* OES_texture_float dependent internal formats */
#define GL_RGBA32F_EXT 0x8814 /* reuse tokens from ARB_texture_float */
#define GL_RGB32F_EXT 0x8815
#define GL_ALPHA32F_EXT 0x8816
#define GL_LUMINANCE32F_EXT 0x8818
#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
/* OES_texture_half_float dependent internal formats */
#define GL_RGBA16F_EXT 0x881A /* reuse tokens from ARB_texture_float */
#define GL_RGB16F_EXT 0x881B
#define GL_ALPHA16F_EXT 0x881C
#define GL_LUMINANCE16F_EXT 0x881E
#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
/* EXT_texture_type_2_10_10_10_REV dependent internal formats */
#define GL_RGB10_A2_EXT 0x8059 /* reuse tokens from EXT_texture */
#define GL_RGB10_EXT 0x8052
/* EXT_texture_format_BGRA8888 dependent internal formats */
#define GL_BGRA8_EXT 0x93A1
#endif
/*------------------------------------------------------------------------*
* DMP extension tokens
*------------------------------------------------------------------------*/
@ -824,6 +866,11 @@ GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLs
typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
#endif
/* GL_ANGLE_texture_usage */
#ifndef GL_ANGLE_texture_usage
#define GL_ANGLE_texture_usage 1
#endif
/*------------------------------------------------------------------------*
* APPLE extension functions
*------------------------------------------------------------------------*/
@ -931,6 +978,30 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
#define GL_EXT_unpack_subimage 1
#endif
/* GL_EXT_robustness */
#ifndef GL_EXT_robustness
#define GL_EXT_robustness 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
#endif /* GL_GLEXT_PROTOTYPES */
typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
#endif
/* GL_EXT_texture_storage */
#ifndef GL_EXT_texture_storage
#define GL_EXT_texture_storage 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY TexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXT) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
#endif
/*------------------------------------------------------------------------*
* DMP extension functions
*------------------------------------------------------------------------*/

Просмотреть файл

@ -1,7 +1,7 @@
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 809
#define BUILD_REVISION 885
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)

Просмотреть файл

@ -624,7 +624,7 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
switch(type) {
case SH_FRAGMENT_SHADER: {
// Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true);
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, false, true);
fragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
}

Просмотреть файл

@ -88,6 +88,7 @@ Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool softwar
mMaxSwapInterval = 1;
mSoftwareDevice = software;
mDisplayId = displayId;
mDeviceLost = false;
}
Display::~Display()
@ -304,7 +305,7 @@ void Display::terminate()
if (mDevice)
{
// If the device is lost, reset it first to prevent leaving the driver in an unstable state
if (isDeviceLost())
if (testDeviceLost())
{
resetDevice();
}
@ -457,23 +458,44 @@ bool Display::createDevice()
bool Display::resetDevice()
{
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
HRESULT result;
do
HRESULT result = D3D_OK;
bool lost = testDeviceLost();
int attempts = 3;
while (lost && attempts > 0)
{
Sleep(0); // Give the graphics driver some CPU time
if (mDeviceEx)
{
Sleep(500); // Give the graphics driver some CPU time
result = mDeviceEx->ResetEx(&presentParameters, NULL);
}
else
{
result = mDevice->TestCooperativeLevel();
result = mDevice->Reset(&presentParameters);
while (result == D3DERR_DEVICELOST)
{
Sleep(100); // Give the graphics driver some CPU time
result = mDevice->TestCooperativeLevel();
}
if (result == D3DERR_DEVICENOTRESET)
{
result = mDevice->Reset(&presentParameters);
}
}
lost = testDeviceLost();
attempts --;
}
while (result == D3DERR_DEVICELOST);
if (FAILED(result))
{
ERR("Reset/ResetEx failed multiple times: 0x%08X", result);
return error(EGL_BAD_ALLOC, false);
}
ASSERT(SUCCEEDED(result));
return true;
}
@ -515,7 +537,8 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
if (isDeviceLost()) {
if (testDeviceLost())
{
if (!restoreLostDevice())
return EGL_NO_SURFACE;
}
@ -627,7 +650,8 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
if (isDeviceLost()) {
if (testDeviceLost())
{
if (!restoreLostDevice())
return EGL_NO_SURFACE;
}
@ -645,7 +669,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return success(surface);
}
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
if (!mDevice)
{
@ -654,7 +678,7 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
return NULL;
}
}
else if (isDeviceLost()) // Lost device
else if (testDeviceLost()) // Lost device
{
if (!restoreLostDevice())
return NULL;
@ -662,14 +686,21 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
const egl::Config *config = mConfigSet.get(configHandle);
gl::Context *context = glCreateContext(config, shareContext);
gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess);
mContextSet.insert(context);
mDeviceLost = false;
return context;
}
bool Display::restoreLostDevice()
{
for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
{
if ((*ctx)->isResetNotificationEnabled())
return false; // If reset notifications have been requested, application must delete all contexts first
}
// Release surface resources to make the Reset() succeed
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
@ -703,6 +734,21 @@ void Display::destroyContext(gl::Context *context)
mContextSet.erase(context);
}
void Display::notifyDeviceLost()
{
for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
{
(*context)->markContextLost();
}
mDeviceLost = true;
error(EGL_CONTEXT_LOST);
}
bool Display::isDeviceLost()
{
return mDeviceLost;
}
bool Display::isInitialized() const
{
return mD3d9 != NULL && mConfigSet.size() > 0;
@ -769,13 +815,13 @@ D3DADAPTER_IDENTIFIER9 *Display::getAdapterIdentifier()
return &mAdapterIdentifier;
}
bool Display::isDeviceLost()
bool Display::testDeviceLost()
{
if (mDeviceEx)
{
return FAILED(mDeviceEx->CheckDeviceState(NULL));
}
else if(mDevice)
else if (mDevice)
{
return FAILED(mDevice->TestCooperativeLevel());
}
@ -783,6 +829,29 @@ bool Display::isDeviceLost()
return false; // No device yet, so no reset required
}
bool Display::testDeviceResettable()
{
HRESULT status = D3D_OK;
if (mDeviceEx)
{
status = mDeviceEx->CheckDeviceState(NULL);
}
else if (mDevice)
{
status = mDevice->TestCooperativeLevel();
}
switch (status)
{
case D3DERR_DEVICENOTRESET:
case D3DERR_DEVICEHUNG:
return true;
default:
return false;
}
}
void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
{
for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
@ -818,7 +887,7 @@ bool Display::getDXT5TextureSupport()
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
}
bool Display::getFloatTextureSupport(bool *filtering, bool *renderable)
bool Display::getFloat32TextureSupport(bool *filtering, bool *renderable)
{
D3DDISPLAYMODE currentDisplayMode;
mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
@ -846,7 +915,7 @@ bool Display::getFloatTextureSupport(bool *filtering, bool *renderable)
}
}
bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable)
bool Display::getFloat16TextureSupport(bool *filtering, bool *renderable)
{
D3DDISPLAYMODE currentDisplayMode;
mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
@ -907,6 +976,23 @@ D3DPOOL Display::getBufferPool(DWORD usage) const
return D3DPOOL_DEFAULT;
}
D3DPOOL Display::getTexturePool(bool renderable) const
{
if (mD3d9Ex != NULL)
{
return D3DPOOL_DEFAULT;
}
else
{
if (!renderable)
{
return D3DPOOL_MANAGED;
}
}
return D3DPOOL_DEFAULT;
}
bool Display::getEventQuerySupport()
{
IDirect3DQuery9 *query;
@ -948,6 +1034,10 @@ void Display::initExtensionString()
mExtensionString = "";
// Multi-vendor (EXT) extensions
mExtensionString += "EGL_EXT_create_context_robustness ";
// ANGLE-specific extensions
if (isd3d9ex) {
mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
}

Просмотреть файл

@ -44,7 +44,7 @@ class Display
EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
void destroySurface(egl::Surface *surface);
void destroyContext(gl::Context *context);
@ -61,19 +61,24 @@ class Display
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
virtual D3DADAPTER_IDENTIFIER9 *getAdapterIdentifier();
bool isDeviceLost();
virtual bool testDeviceLost();
virtual bool testDeviceResettable();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getDXT1TextureSupport();
virtual bool getDXT3TextureSupport();
virtual bool getDXT5TextureSupport();
virtual bool getEventQuerySupport();
virtual bool getFloatTextureSupport(bool *filtering, bool *renderable);
virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable);
virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
virtual bool getLuminanceTextureSupport();
virtual bool getLuminanceAlphaTextureSupport();
virtual bool getVertexTextureSupport() const;
virtual bool getNonPower2TextureSupport() const;
virtual D3DPOOL getBufferPool(DWORD usage) const;
virtual D3DPOOL getTexturePool(bool renderable) const;
virtual void notifyDeviceLost();
bool isDeviceLost();
bool isD3d9ExDevice() { return mD3d9Ex != NULL; }
const char *getExtensionString() const;
@ -114,6 +119,7 @@ class Display
typedef std::set<gl::Context*> ContextSet;
ContextSet mContextSet;
bool mDeviceLost;
bool createDevice();
bool resetDevice();

Просмотреть файл

@ -106,7 +106,7 @@ bool Surface::initialize()
result = DwmSetPresentParameters(mWindow, &presentParams);
if (FAILED(result))
ERR("Unable to set present parameters: %081X", result);
ERR("Unable to set present parameters: 0x%08X", result);
}
}
@ -250,11 +250,20 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
release();
return error(EGL_BAD_ALLOC, false);
if(isDeviceLostError(result))
{
mDisplay->notifyDeviceLost();
return false;
}
else
{
return error(EGL_BAD_ALLOC, false);
}
}
if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
@ -268,7 +277,7 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
release();
return error(EGL_BAD_ALLOC, false);
}
@ -413,14 +422,15 @@ bool Surface::swap()
HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(EGL_BAD_ALLOC, false);
}
if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED)
if (isDeviceLostError(result))
{
return error(EGL_CONTEXT_LOST, false);
mDisplay->notifyDeviceLost();
return false;
}
ASSERT(SUCCEEDED(result));

Просмотреть файл

@ -715,7 +715,10 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
return error(EGL_BAD_MATCH, EGL_FALSE);
}
glBindTexImage(eglSurface);
if (!glBindTexImage(eglSurface))
{
return error(EGL_BAD_MATCH, EGL_FALSE);
}
return success(EGL_TRUE);
}
@ -814,16 +817,34 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
{
// Get the requested client version (default is 1) and check it is two.
EGLint client_version = 1;
bool reset_notification = false;
bool robust_access = false;
if (attrib_list)
{
for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
{
if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
switch (attribute[0])
{
case EGL_CONTEXT_CLIENT_VERSION:
client_version = attribute[1];
}
else
{
break;
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
if (attribute[1] == EGL_TRUE)
{
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
robust_access = true;
}
else if (attribute[1] != EGL_FALSE)
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
break;
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
reset_notification = true;
else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
break;
default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
}
}
@ -834,6 +855,11 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
}
if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification)
{
return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
}
egl::Display *display = static_cast<egl::Display*>(dpy);
if (!validateConfig(display, config))
@ -841,9 +867,12 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return EGL_NO_CONTEXT;
}
EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
return success(context);
if (context)
return success(context);
else
return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
}
catch(std::bad_alloc&)
{
@ -895,7 +924,13 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
gl::Context *context = static_cast<gl::Context*>(ctx);
IDirect3DDevice9 *device = display->getDevice();
if (!device || display->isDeviceLost())
if (!device || display->testDeviceLost())
{
display->notifyDeviceLost();
return EGL_FALSE;
}
if (display->isDeviceLost())
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
@ -1077,6 +1112,11 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
return EGL_FALSE;
}
if (display->isDeviceLost())
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE)
{
return error(EGL_BAD_SURFACE, EGL_FALSE);
@ -1109,6 +1149,11 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
return EGL_FALSE;
}
if (display->isDeviceLost())
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
UNIMPLEMENTED(); // FIXME
return success(0);

Просмотреть файл

@ -38,8 +38,10 @@ namespace
namespace gl
{
Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
Context::Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess) : mConfig(config)
{
ASSERT(robustAccess == false); // Unimplemented
mDisplay = NULL;
mDevice = NULL;
@ -158,6 +160,10 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext) : m
mInvalidFramebufferOperation = false;
mHasBeenCurrent = false;
mContextLost = false;
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
mSupportsDXT1Textures = false;
mSupportsDXT3Textures = false;
@ -290,8 +296,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mSupportsDXT1Textures = mDisplay->getDXT1TextureSupport();
mSupportsDXT3Textures = mDisplay->getDXT3TextureSupport();
mSupportsDXT5Textures = mDisplay->getDXT5TextureSupport();
mSupportsFloatTextures = mDisplay->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
mSupportsHalfFloatTextures = mDisplay->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
mSupportsFloat32Textures = mDisplay->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
mSupportsFloat16Textures = mDisplay->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
mSupportsLuminanceTextures = mDisplay->getLuminanceTextureSupport();
mSupportsLuminanceAlphaTextures = mDisplay->getLuminanceAlphaTextureSupport();
@ -389,6 +395,18 @@ void Context::markAllStateDirty()
mCachedCurrentProgram = NULL;
}
void Context::markContextLost()
{
if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
mContextLost = true;
}
bool Context::isContextLost()
{
return mContextLost;
}
void Context::setClearColor(float red, float green, float blue, float alpha)
{
mState.colorClearValue.red = red;
@ -1158,24 +1176,25 @@ bool Context::getBooleanv(GLenum pname, GLboolean *params)
{
switch (pname)
{
case GL_SHADER_COMPILER: *params = GL_TRUE; break;
case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
case GL_SHADER_COMPILER: *params = GL_TRUE; break;
case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
case GL_COLOR_WRITEMASK:
params[0] = mState.colorMaskRed;
params[1] = mState.colorMaskGreen;
params[2] = mState.colorMaskBlue;
params[3] = mState.colorMaskAlpha;
break;
case GL_CULL_FACE: *params = mState.cullFace; break;
case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
case GL_STENCIL_TEST: *params = mState.stencilTest; break;
case GL_DEPTH_TEST: *params = mState.depthTest; break;
case GL_BLEND: *params = mState.blend; break;
case GL_DITHER: *params = mState.dither; break;
case GL_CULL_FACE: *params = mState.cullFace; break;
case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
case GL_STENCIL_TEST: *params = mState.stencilTest; break;
case GL_DEPTH_TEST: *params = mState.depthTest; break;
case GL_BLEND: *params = mState.blend; break;
case GL_DITHER: *params = mState.dither; break;
case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
default:
return false;
}
@ -1375,7 +1394,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_ALPHA_BITS:
{
gl::Framebuffer *framebuffer = getDrawFramebuffer();
gl::Colorbuffer *colorbuffer = framebuffer->getColorbuffer();
gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
if (colorbuffer)
{
@ -1396,7 +1415,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_DEPTH_BITS:
{
gl::Framebuffer *framebuffer = getDrawFramebuffer();
gl::DepthStencilbuffer *depthbuffer = framebuffer->getDepthbuffer();
gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
if (depthbuffer)
{
@ -1411,7 +1430,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_STENCIL_BITS:
{
gl::Framebuffer *framebuffer = getDrawFramebuffer();
gl::DepthStencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
if (stencilbuffer)
{
@ -1445,6 +1464,9 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
}
break;
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
*params = mResetStrategy;
break;
default:
return false;
}
@ -1534,6 +1556,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
{
*type = GL_INT;
*numParams = 1;
@ -1577,6 +1600,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_DEPTH_TEST:
case GL_BLEND:
case GL_DITHER:
case GL_CONTEXT_ROBUST_ACCESS_EXT:
{
*type = GL_BOOL;
*numParams = 1;
@ -1730,7 +1754,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
return false; // Nothing to render
}
if (!mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0)
if (renderTargetChanged || !mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0)
{
mDevice->SetViewport(&viewport);
mSetViewport = viewport;
@ -1911,7 +1935,7 @@ void Context::applyState(GLenum drawMode)
}
// get the maximum size of the stencil ref
gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
gl::Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
@ -1978,7 +2002,7 @@ void Context::applyState(GLenum drawMode)
{
if (mState.polygonOffsetFill)
{
gl::DepthStencilbuffer *depthbuffer = framebufferObject->getDepthbuffer();
gl::Renderbuffer *depthbuffer = framebufferObject->getDepthbuffer();
if (depthbuffer)
{
mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
@ -2127,13 +2151,13 @@ void Context::applyTextures(SamplerType type)
Texture *texture = getSamplerTexture(textureUnit, textureType);
if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter() || texture->isDirtyImage())
if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyParameters() || texture->hasDirtyImages())
{
IDirect3DBaseTexture9 *d3dTexture = texture->getTexture();
if (d3dTexture)
{
if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyParameter())
if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyParameters())
{
GLenum wrapS = texture->getWrapS();
GLenum wrapT = texture->getWrapT();
@ -2150,7 +2174,7 @@ void Context::applyTextures(SamplerType type)
mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
}
if (appliedTextureSerial[samplerIndex] != texture->getSerial() || texture->isDirtyImage())
if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyImages())
{
mDevice->SetTexture(d3dSampler, d3dTexture);
}
@ -2160,7 +2184,7 @@ void Context::applyTextures(SamplerType type)
mDevice->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
}
appliedTextureSerial[samplerIndex] = texture->getSerial();
appliedTextureSerial[samplerIndex] = texture->getTextureSerial();
texture->resetDirty();
}
}
@ -2184,7 +2208,8 @@ void Context::applyTextures(SamplerType type)
}
}
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
Framebuffer *framebuffer = getReadFramebuffer();
@ -2198,6 +2223,17 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
return error(GL_INVALID_OPERATION);
}
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
// sized query sanity check
if (bufSize)
{
int requiredSize = outputPitch * height;
if (requiredSize > *bufSize)
{
return error(GL_INVALID_OPERATION);
}
}
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
if (!renderTarget)
@ -2229,18 +2265,16 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
{
systemSurface->Release();
switch (result)
{
// It turns out that D3D will sometimes produce more error
// codes than those documented.
case D3DERR_DRIVERINTERNALERROR:
case D3DERR_DEVICELOST:
case D3DERR_DEVICEHUNG:
// It turns out that D3D will sometimes produce more error
// codes than those documented.
if (checkDeviceLost(result))
return error(GL_OUT_OF_MEMORY);
default:
else
{
UNREACHABLE();
return; // No sensible error to generate
return;
}
}
D3DLOCKED_RECT lock;
@ -2264,7 +2298,6 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
unsigned char *dest = (unsigned char*)pixels;
unsigned short *dest16 = (unsigned short*)pixels;
int inputPitch = -lock.Pitch;
GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
for (int j = 0; j < rect.bottom - rect.top; j++)
{
@ -2826,7 +2859,7 @@ void Context::sync(bool block)
eventQuery->Release();
if (result == D3DERR_DEVICELOST)
if (checkDeviceLost(result))
{
error(GL_OUT_OF_MEMORY);
}
@ -2994,6 +3027,36 @@ GLenum Context::getError()
return GL_NO_ERROR;
}
GLenum Context::getResetStatus()
{
if (mResetStatus == GL_NO_ERROR)
{
bool lost = mDisplay->testDeviceLost();
if (lost)
{
mDisplay->notifyDeviceLost(); // Sets mResetStatus
}
}
GLenum status = mResetStatus;
if (mResetStatus != GL_NO_ERROR)
{
if (mDisplay->testDeviceResettable())
{
mResetStatus = GL_NO_ERROR;
}
}
return status;
}
bool Context::isResetNotificationEnabled()
{
return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
}
bool Context::supportsShaderModel3() const
{
return mSupportsShaderModel3;
@ -3068,34 +3131,34 @@ bool Context::supportsDXT5Textures() const
return mSupportsDXT5Textures;
}
bool Context::supportsFloatTextures() const
bool Context::supportsFloat32Textures() const
{
return mSupportsFloatTextures;
return mSupportsFloat32Textures;
}
bool Context::supportsFloatLinearFilter() const
bool Context::supportsFloat32LinearFilter() const
{
return mSupportsFloatLinearFilter;
return mSupportsFloat32LinearFilter;
}
bool Context::supportsFloatRenderableTextures() const
bool Context::supportsFloat32RenderableTextures() const
{
return mSupportsFloatRenderableTextures;
return mSupportsFloat32RenderableTextures;
}
bool Context::supportsHalfFloatTextures() const
bool Context::supportsFloat16Textures() const
{
return mSupportsHalfFloatTextures;
return mSupportsFloat16Textures;
}
bool Context::supportsHalfFloatLinearFilter() const
bool Context::supportsFloat16LinearFilter() const
{
return mSupportsHalfFloatLinearFilter;
return mSupportsFloat16LinearFilter;
}
bool Context::supportsHalfFloatRenderableTextures() const
bool Context::supportsFloat16RenderableTextures() const
{
return mSupportsHalfFloatRenderableTextures;
return mSupportsFloat16RenderableTextures;
}
int Context::getMaximumRenderbufferDimension() const
@ -3344,19 +3407,19 @@ void Context::initExtensionString()
mExtensionString += "GL_OES_rgb8_rgba8 ";
mExtensionString += "GL_OES_standard_derivatives ";
if (supportsHalfFloatTextures())
if (supportsFloat16Textures())
{
mExtensionString += "GL_OES_texture_half_float ";
}
if (supportsHalfFloatLinearFilter())
if (supportsFloat16LinearFilter())
{
mExtensionString += "GL_OES_texture_half_float_linear ";
}
if (supportsFloatTextures())
if (supportsFloat32Textures())
{
mExtensionString += "GL_OES_texture_float ";
}
if (supportsFloatLinearFilter())
if (supportsFloat32LinearFilter())
{
mExtensionString += "GL_OES_texture_float_linear ";
}
@ -3368,6 +3431,7 @@ void Context::initExtensionString()
// Multi-vendor (EXT) extensions
mExtensionString += "GL_EXT_read_format_bgra ";
mExtensionString += "GL_EXT_robustness ";
if (supportsDXT1Textures())
{
@ -3375,6 +3439,7 @@ void Context::initExtensionString()
}
mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
mExtensionString += "GL_EXT_texture_storage ";
// ANGLE-specific extensions
mExtensionString += "GL_ANGLE_framebuffer_blit ";
@ -3391,6 +3456,8 @@ void Context::initExtensionString()
{
mExtensionString += "GL_ANGLE_texture_compression_dxt5 ";
}
mExtensionString += "GL_ANGLE_texture_usage ";
mExtensionString += "GL_ANGLE_translated_shader_source ";
// Other vendor-specific extensions
@ -3616,8 +3683,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
{
DepthStencilbuffer *readDSBuffer = NULL;
DepthStencilbuffer *drawDSBuffer = NULL;
Renderbuffer *readDSBuffer = NULL;
Renderbuffer *drawDSBuffer = NULL;
// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
// both a depth and stencil buffer, it will be the same buffer.
@ -3805,9 +3872,9 @@ void VertexDeclarationCache::markStateDirty()
extern "C"
{
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext)
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
return new gl::Context(config, shareContext);
return new gl::Context(config, shareContext, notifyResets, robustAccess);
}
void glDestroyContext(gl::Context *context)

Просмотреть файл

@ -258,7 +258,7 @@ class VertexDeclarationCache
class Context
{
public:
Context(const egl::Config *config, const gl::Context *shareContext);
Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
~Context();
@ -266,6 +266,9 @@ class Context
void markAllStateDirty();
virtual void markContextLost();
bool isContextLost();
// State manipulation
void setClearColor(float red, float green, float blue, float alpha);
@ -417,7 +420,7 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
@ -434,6 +437,8 @@ class Context
void recordInvalidFramebufferOperation();
GLenum getError();
GLenum getResetStatus();
virtual bool isResetNotificationEnabled();
bool supportsShaderModel3() const;
int getMaximumVaryingVectors() const;
@ -452,12 +457,12 @@ class Context
bool supportsDXT1Textures() const;
bool supportsDXT3Textures() const;
bool supportsDXT5Textures() const;
bool supportsFloatTextures() const;
bool supportsFloatLinearFilter() const;
bool supportsFloatRenderableTextures() const;
bool supportsHalfFloatTextures() const;
bool supportsHalfFloatLinearFilter() const;
bool supportsHalfFloatRenderableTextures() const;
bool supportsFloat32Textures() const;
bool supportsFloat32LinearFilter() const;
bool supportsFloat32RenderableTextures() const;
bool supportsFloat16Textures() const;
bool supportsFloat16LinearFilter() const;
bool supportsFloat16RenderableTextures() const;
bool supportsLuminanceTextures() const;
bool supportsLuminanceAlphaTextures() const;
bool supports32bitIndices() const;
@ -531,7 +536,12 @@ class Context
bool mOutOfMemory;
bool mInvalidFramebufferOperation;
// Current/lost context flags
bool mHasBeenCurrent;
bool mContextLost;
GLenum mResetStatus;
GLenum mResetStrategy;
bool mRobustAccess;
unsigned int mAppliedTextureSerialPS[MAX_TEXTURE_IMAGE_UNITS];
unsigned int mAppliedTextureSerialVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
@ -562,12 +572,12 @@ class Context
bool mSupportsDXT1Textures;
bool mSupportsDXT3Textures;
bool mSupportsDXT5Textures;
bool mSupportsFloatTextures;
bool mSupportsFloatLinearFilter;
bool mSupportsFloatRenderableTextures;
bool mSupportsHalfFloatTextures;
bool mSupportsHalfFloatLinearFilter;
bool mSupportsHalfFloatRenderableTextures;
bool mSupportsFloat32Textures;
bool mSupportsFloat32LinearFilter;
bool mSupportsFloat32RenderableTextures;
bool mSupportsFloat16Textures;
bool mSupportsFloat16LinearFilter;
bool mSupportsFloat16RenderableTextures;
bool mSupportsLuminanceTextures;
bool mSupportsLuminanceAlphaTextures;
bool mSupports32bitIndices;
@ -600,12 +610,12 @@ class Context
extern "C"
{
// Exported functions for use by EGL
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext);
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
void glDestroyContext(gl::Context *context);
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
gl::Context *glGetCurrentContext();
__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
void __stdcall glBindTexImage(egl::Surface *surface);
bool __stdcall glBindTexImage(egl::Surface *surface);
}
#endif // INCLUDE_CONTEXT_H_

Просмотреть файл

@ -65,7 +65,7 @@ GLboolean Fence::testFence()
HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
if (result == D3DERR_DEVICELOST)
if (checkDeviceLost(result))
{
return error(GL_OUT_OF_MEMORY, GL_TRUE);
}
@ -110,7 +110,7 @@ void Fence::getFenceiv(GLenum pname, GLint *params)
HRESULT result = mQuery->GetData(NULL, 0, 0);
if (result == D3DERR_DEVICELOST)
if (checkDeviceLost(result))
{
params[0] = GL_TRUE;
return error(GL_OUT_OF_MEMORY);

Просмотреть файл

@ -181,46 +181,19 @@ unsigned int Framebuffer::getStencilbufferSerial()
return 0;
}
Colorbuffer *Framebuffer::getColorbuffer()
Renderbuffer *Framebuffer::getColorbuffer()
{
Renderbuffer *rb = mColorbufferPointer.get();
if (rb != NULL && rb->isColorbuffer())
{
return static_cast<Colorbuffer*>(rb->getStorage());
}
else
{
return NULL;
}
return mColorbufferPointer.get();
}
DepthStencilbuffer *Framebuffer::getDepthbuffer()
Renderbuffer *Framebuffer::getDepthbuffer()
{
Renderbuffer *rb = mDepthbufferPointer.get();
if (rb != NULL && rb->isDepthbuffer())
{
return static_cast<DepthStencilbuffer*>(rb->getStorage());
}
else
{
return NULL;
}
return mDepthbufferPointer.get();
}
DepthStencilbuffer *Framebuffer::getStencilbuffer()
Renderbuffer *Framebuffer::getStencilbuffer()
{
Renderbuffer *rb = mStencilbufferPointer.get();
if (rb != NULL && rb->isStencilbuffer())
{
return static_cast<DepthStencilbuffer*>(rb->getStorage());
}
else
{
return NULL;
}
return mStencilbufferPointer.get();
}
GLenum Framebuffer::getColorbufferType()
@ -257,7 +230,7 @@ bool Framebuffer::hasStencil()
{
if (mStencilbufferType != GL_NONE)
{
DepthStencilbuffer *stencilbufferObject = getStencilbuffer();
Renderbuffer *stencilbufferObject = getStencilbuffer();
if (stencilbufferObject)
{
@ -276,7 +249,7 @@ GLenum Framebuffer::completeness()
if (mColorbufferType != GL_NONE)
{
Colorbuffer *colorbuffer = getColorbuffer();
Renderbuffer *colorbuffer = getColorbuffer();
if (!colorbuffer)
{
@ -302,8 +275,8 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_UNSUPPORTED;
}
if ((colorbuffer->getType() == GL_FLOAT && !getContext()->supportsFloatRenderableTextures()) ||
(colorbuffer->getType() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatRenderableTextures()))
if ((dx2es::IsFloat32Format(colorbuffer->getD3DFormat()) && !getContext()->supportsFloat32RenderableTextures()) ||
(dx2es::IsFloat16Format(colorbuffer->getD3DFormat()) && !getContext()->supportsFloat16RenderableTextures()))
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
@ -324,8 +297,8 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
}
DepthStencilbuffer *depthbuffer = NULL;
DepthStencilbuffer *stencilbuffer = NULL;
Renderbuffer *depthbuffer = NULL;
Renderbuffer *stencilbuffer = NULL;
if (mDepthbufferType != GL_NONE)
{
@ -418,17 +391,17 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_COMPLETE;
}
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
mColorbufferType = GL_RENDERBUFFER;
mDepthbufferType = (depthStencil->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mStencilbufferType = (depthStencil->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mColorbufferPointer.set(new Renderbuffer(0, color));
mColorbufferPointer.set(new Renderbuffer(0, colorbuffer));
Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
mDepthbufferPointer.set(depthStencilRenderbuffer);
mStencilbufferPointer.set(depthStencilRenderbuffer);
mColorbufferType = GL_RENDERBUFFER;
mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
}
int Framebuffer::getSamples()

Просмотреть файл

@ -46,9 +46,9 @@ class Framebuffer
unsigned int getDepthbufferSerial();
unsigned int getStencilbufferSerial();
Colorbuffer *getColorbuffer();
DepthStencilbuffer *getDepthbuffer();
DepthStencilbuffer *getStencilbuffer();
Renderbuffer *getColorbuffer();
Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer();
GLenum getColorbufferType();
GLenum getDepthbufferType();
@ -82,7 +82,7 @@ class Framebuffer
class DefaultFramebuffer : public Framebuffer
{
public:
DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil);
DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
virtual GLenum completeness();

Просмотреть файл

@ -36,7 +36,7 @@ std::string str(int i)
Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize)
: type(type), _name(_name), name(Program::undecorateUniform(_name)), arraySize(arraySize)
{
int bytes = UniformTypeSize(type) * arraySize;
int bytes = UniformInternalSize(type) * arraySize;
data = new unsigned char[bytes];
memset(data, 0, bytes);
dirty = true;
@ -560,7 +560,7 @@ void transposeMatrix(T *target, const GLfloat *value)
{
for (int y = 0; y < copyHeight; y++)
{
target[x * targetWidth + y] = value[y * srcWidth + x];
target[x * targetWidth + y] = (T)value[y * srcWidth + x];
}
}
// clear unfilled right side
@ -568,7 +568,7 @@ void transposeMatrix(T *target, const GLfloat *value)
{
for (int x = srcWidth; x < targetWidth; x++)
{
target[y * targetWidth + x] = 0;
target[y * targetWidth + x] = (T)0;
}
}
// clear unfilled bottom.
@ -576,7 +576,7 @@ void transposeMatrix(T *target, const GLfloat *value)
{
for (int x = 0; x < targetWidth; x++)
{
target[y * targetWidth + x] = 0;
target[y * targetWidth + x] = (T)0;
}
}
}
@ -911,7 +911,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
return true;
}
bool Program::getUniformfv(GLint location, GLfloat *params)
bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
{
if (location < 0 || location >= (int)mUniformIndex.size())
{
@ -920,6 +920,16 @@ bool Program::getUniformfv(GLint location, GLfloat *params)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
// sized queries -- ensure the provided buffer is large enough
if (bufSize)
{
int requiredBytes = UniformExternalSize(targetUniform->type);
if (*bufSize < requiredBytes)
{
return false;
}
}
switch (targetUniform->type)
{
case GL_FLOAT_MAT2:
@ -933,7 +943,7 @@ bool Program::getUniformfv(GLint location, GLfloat *params)
break;
default:
{
unsigned int count = UniformComponentCount(targetUniform->type);
unsigned int count = UniformExternalComponentCount(targetUniform->type);
unsigned int internalCount = UniformInternalComponentCount(targetUniform->type);
switch (UniformComponentType(targetUniform->type))
@ -970,7 +980,7 @@ bool Program::getUniformfv(GLint location, GLfloat *params)
return true;
}
bool Program::getUniformiv(GLint location, GLint *params)
bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
{
if (location < 0 || location >= (int)mUniformIndex.size())
{
@ -979,6 +989,16 @@ bool Program::getUniformiv(GLint location, GLint *params)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
// sized queries -- ensure the provided buffer is large enough
if (bufSize)
{
int requiredBytes = UniformExternalSize(targetUniform->type);
if (*bufSize < requiredBytes)
{
return false;
}
}
switch (targetUniform->type)
{
case GL_FLOAT_MAT2:
@ -998,7 +1018,7 @@ bool Program::getUniformiv(GLint location, GLint *params)
break;
default:
{
unsigned int count = UniformComponentCount(targetUniform->type);
unsigned int count = UniformExternalComponentCount(targetUniform->type);
unsigned int internalCount = UniformInternalComponentCount(targetUniform->type);
switch (UniformComponentType(targetUniform->type))
@ -1834,10 +1854,15 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
{
if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{
for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++)
for (unsigned int i = 0; i < constantDescription.RegisterCount; i++)
{
if (mConstantTablePS->GetConstantByName(NULL, constantDescription.Name) != NULL)
D3DXHANDLE psConstant = mConstantTablePS->GetConstantByName(NULL, constantDescription.Name);
D3DXHANDLE vsConstant = mConstantTableVS->GetConstantByName(NULL, constantDescription.Name);
if (psConstant)
{
unsigned int samplerIndex = mConstantTablePS->GetSamplerIndex(psConstant) + i;
if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
{
mSamplersPS[samplerIndex].active = true;
@ -1852,8 +1877,10 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
}
}
if (mConstantTableVS->GetConstantByName(NULL, constantDescription.Name) != NULL)
if (vsConstant)
{
unsigned int samplerIndex = mConstantTableVS->GetSamplerIndex(vsConstant) + i;
if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits())
{
mSamplersVS[samplerIndex].active = true;

Просмотреть файл

@ -98,8 +98,8 @@ class Program
bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
bool getUniformfv(GLint location, GLfloat *params);
bool getUniformiv(GLint location, GLint *params);
bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
GLint getDxDepthRangeLocation() const;
GLint getDxDepthLocation() const;

Просмотреть файл

@ -18,103 +18,175 @@ namespace gl
{
unsigned int RenderbufferStorage::mCurrentSerial = 1;
Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
RenderbufferInterface::RenderbufferInterface()
{
ASSERT(storage != NULL);
mStorage = storage;
}
GLuint RenderbufferInterface::getRedSize() const
{
return dx2es::GetRedSize(getD3DFormat());
}
GLuint RenderbufferInterface::getGreenSize() const
{
return dx2es::GetGreenSize(getD3DFormat());
}
GLuint RenderbufferInterface::getBlueSize() const
{
return dx2es::GetBlueSize(getD3DFormat());
}
GLuint RenderbufferInterface::getAlphaSize() const
{
return dx2es::GetAlphaSize(getD3DFormat());
}
GLuint RenderbufferInterface::getDepthSize() const
{
return dx2es::GetDepthSize(getD3DFormat());
}
GLuint RenderbufferInterface::getStencilSize() const
{
return dx2es::GetStencilSize(getD3DFormat());
}
RenderbufferTexture::RenderbufferTexture(Texture *texture, GLenum target) : mTexture(texture), mTarget(target)
{
}
RenderbufferTexture::~RenderbufferTexture()
{
}
IDirect3DSurface9 *RenderbufferTexture::getRenderTarget()
{
return mTexture->getRenderTarget(mTarget);
}
IDirect3DSurface9 *RenderbufferTexture::getDepthStencil()
{
return NULL;
}
GLsizei RenderbufferTexture::getWidth() const
{
return mTexture->getWidth();
}
GLsizei RenderbufferTexture::getHeight() const
{
return mTexture->getHeight();
}
GLenum RenderbufferTexture::getInternalFormat() const
{
return mTexture->getInternalFormat();
}
D3DFORMAT RenderbufferTexture::getD3DFormat() const
{
return mTexture->getD3DFormat();
}
GLsizei RenderbufferTexture::getSamples() const
{
return 0;
}
unsigned int RenderbufferTexture::getSerial() const
{
return mTexture->getRenderTargetSerial(mTarget);
}
Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
{
ASSERT(instance != NULL);
mInstance = instance;
}
Renderbuffer::~Renderbuffer()
{
delete mStorage;
}
bool Renderbuffer::isColorbuffer() const
{
return mStorage->isColorbuffer();
}
bool Renderbuffer::isDepthbuffer() const
{
return mStorage->isDepthbuffer();
}
bool Renderbuffer::isStencilbuffer() const
{
return mStorage->isStencilbuffer();
delete mInstance;
}
IDirect3DSurface9 *Renderbuffer::getRenderTarget()
{
return mStorage->getRenderTarget();
return mInstance->getRenderTarget();
}
IDirect3DSurface9 *Renderbuffer::getDepthStencil()
{
return mStorage->getDepthStencil();
return mInstance->getDepthStencil();
}
GLsizei Renderbuffer::getWidth() const
{
return mStorage->getWidth();
return mInstance->getWidth();
}
GLsizei Renderbuffer::getHeight() const
{
return mStorage->getHeight();
return mInstance->getHeight();
}
GLenum Renderbuffer::getInternalFormat() const
{
return mStorage->getInternalFormat();
return mInstance->getInternalFormat();
}
D3DFORMAT Renderbuffer::getD3DFormat() const
{
return mInstance->getD3DFormat();
}
GLuint Renderbuffer::getRedSize() const
{
return mStorage->getRedSize();
return mInstance->getRedSize();
}
GLuint Renderbuffer::getGreenSize() const
{
return mStorage->getGreenSize();
return mInstance->getGreenSize();
}
GLuint Renderbuffer::getBlueSize() const
{
return mStorage->getBlueSize();
return mInstance->getBlueSize();
}
GLuint Renderbuffer::getAlphaSize() const
{
return mStorage->getAlphaSize();
return mInstance->getAlphaSize();
}
GLuint Renderbuffer::getDepthSize() const
{
return mStorage->getDepthSize();
return mInstance->getDepthSize();
}
GLuint Renderbuffer::getStencilSize() const
{
return mStorage->getStencilSize();
return mInstance->getStencilSize();
}
GLsizei Renderbuffer::getSamples() const
{
return mStorage->getSamples();
return mInstance->getSamples();
}
unsigned int Renderbuffer::getSerial() const
{
return mStorage->getSerial();
return mInstance->getSerial();
}
void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
{
ASSERT(newStorage != NULL);
delete mStorage;
mStorage = newStorage;
delete mInstance;
mInstance = newStorage;
}
RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
@ -130,21 +202,6 @@ RenderbufferStorage::~RenderbufferStorage()
{
}
bool RenderbufferStorage::isColorbuffer() const
{
return false;
}
bool RenderbufferStorage::isDepthbuffer() const
{
return false;
}
bool RenderbufferStorage::isStencilbuffer() const
{
return false;
}
IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
{
return NULL;
@ -170,34 +227,9 @@ GLenum RenderbufferStorage::getInternalFormat() const
return mInternalFormat;
}
GLuint RenderbufferStorage::getRedSize() const
D3DFORMAT RenderbufferStorage::getD3DFormat() const
{
return dx2es::GetRedSize(getD3DFormat());
}
GLuint RenderbufferStorage::getGreenSize() const
{
return dx2es::GetGreenSize(getD3DFormat());
}
GLuint RenderbufferStorage::getBlueSize() const
{
return dx2es::GetBlueSize(getD3DFormat());
}
GLuint RenderbufferStorage::getAlphaSize() const
{
return dx2es::GetAlphaSize(getD3DFormat());
}
GLuint RenderbufferStorage::getDepthSize() const
{
return dx2es::GetDepthSize(getD3DFormat());
}
GLuint RenderbufferStorage::getStencilSize() const
{
return dx2es::GetStencilSize(getD3DFormat());
return mD3DFormat;
}
GLsizei RenderbufferStorage::getSamples() const
@ -205,11 +237,6 @@ GLsizei RenderbufferStorage::getSamples() const
return mSamples;
}
D3DFORMAT RenderbufferStorage::getD3DFormat() const
{
return mD3DFormat;
}
unsigned int RenderbufferStorage::getSerial() const
{
return mSerial;
@ -220,7 +247,14 @@ unsigned int RenderbufferStorage::issueSerial()
return mCurrentSerial++;
}
Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget), mTexture(NULL)
unsigned int RenderbufferStorage::issueCubeSerials()
{
unsigned int firstSerial = mCurrentSerial;
mCurrentSerial += 6;
return firstSerial;
}
Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
{
if (renderTarget)
{
@ -237,21 +271,7 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render
}
}
Colorbuffer::Colorbuffer(Texture *texture, GLenum target) : mRenderTarget(NULL), mTexture(texture), mTarget(target)
{
if (texture)
{
mWidth = texture->getWidth();
mHeight = texture->getHeight();
mInternalFormat = texture->getInternalFormat();
mD3DFormat = texture->getD3DFormat();
mSamples = 0;
mRenderTarget = texture->getRenderTarget(target);
}
}
Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL), mTexture(NULL)
Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
{
IDirect3DDevice9 *device = getDevice();
@ -295,71 +315,11 @@ Colorbuffer::~Colorbuffer()
}
}
GLsizei Colorbuffer::getWidth() const
{
if (mTexture)
{
return mTexture->getWidth();
}
return mWidth;
}
GLsizei Colorbuffer::getHeight() const
{
if (mTexture)
{
return mTexture->getHeight();
}
return mHeight;
}
GLenum Colorbuffer::getInternalFormat() const
{
if (mTexture)
{
return mTexture->getInternalFormat();
}
return mInternalFormat;
}
GLenum Colorbuffer::getType() const
{
if (mTexture)
{
return mTexture->getType();
}
return GL_UNSIGNED_BYTE;
}
D3DFORMAT Colorbuffer::getD3DFormat() const
{
if (mTexture)
{
return mTexture->getD3DFormat();
}
return mD3DFormat;
}
bool Colorbuffer::isColorbuffer() const
{
return true;
}
IDirect3DSurface9 *Colorbuffer::getRenderTarget()
{
if (mTexture)
if (mRenderTarget)
{
if (mRenderTarget)
{
mRenderTarget->Release();
}
mRenderTarget = mTexture->getRenderTarget(mTarget);
mRenderTarget->AddRef();
}
return mRenderTarget;
@ -427,16 +387,6 @@ DepthStencilbuffer::~DepthStencilbuffer()
}
}
bool DepthStencilbuffer::isDepthbuffer() const
{
return true;
}
bool DepthStencilbuffer::isStencilbuffer() const
{
return true;
}
IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
{
return mDepthStencil;
@ -454,7 +404,7 @@ Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(d
Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
if (getDepthStencil())
if (mDepthStencil)
{
mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
@ -466,16 +416,6 @@ Depthbuffer::~Depthbuffer()
{
}
bool Depthbuffer::isDepthbuffer() const
{
return true;
}
bool Depthbuffer::isStencilbuffer() const
{
return false;
}
Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
{
if (depthStencil)
@ -488,7 +428,7 @@ Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuff
Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
if (getDepthStencil())
if (mDepthStencil)
{
mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
@ -500,13 +440,4 @@ Stencilbuffer::~Stencilbuffer()
{
}
bool Stencilbuffer::isDepthbuffer() const
{
return false;
}
bool Stencilbuffer::isStencilbuffer() const
{
return true;
}
}

Просмотреть файл

@ -22,38 +22,86 @@
namespace gl
{
class Texture;
class Colorbuffer;
class DepthStencilbuffer;
class RenderbufferInterface
{
public:
RenderbufferInterface();
virtual ~RenderbufferInterface() {};
virtual IDirect3DSurface9 *getRenderTarget() = 0;
virtual IDirect3DSurface9 *getDepthStencil() = 0;
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0;
virtual D3DFORMAT getD3DFormat() const = 0;
virtual GLsizei getSamples() const = 0;
GLuint getRedSize() const;
GLuint getGreenSize() const;
GLuint getBlueSize() const;
GLuint getAlphaSize() const;
GLuint getDepthSize() const;
GLuint getStencilSize() const;
virtual unsigned int getSerial() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(RenderbufferInterface);
};
class RenderbufferTexture : public RenderbufferInterface
{
public:
RenderbufferTexture(Texture *texture, GLenum target);
virtual ~RenderbufferTexture();
IDirect3DSurface9 *getRenderTarget();
IDirect3DSurface9 *getDepthStencil();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual D3DFORMAT getD3DFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
private:
DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture);
Texture *mTexture;
GLenum mTarget;
};
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
// is called. The specific concrete type depends on whether the internal format is
// colour depth, stencil or packed depth/stencil.
class RenderbufferStorage
class RenderbufferStorage : public RenderbufferInterface
{
public:
RenderbufferStorage();
virtual ~RenderbufferStorage() = 0;
virtual bool isColorbuffer() const;
virtual bool isDepthbuffer() const;
virtual bool isStencilbuffer() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
GLuint getRedSize() const;
GLuint getGreenSize() const;
GLuint getBlueSize() const;
GLuint getAlphaSize() const;
GLuint getDepthSize() const;
GLuint getStencilSize() const;
virtual D3DFORMAT getD3DFormat() const;
virtual GLsizei getSamples() const;
virtual D3DFORMAT getD3DFormat() const;
virtual unsigned int getSerial() const;
unsigned int getSerial() const;
static unsigned int issueSerial();
static unsigned int issueCubeSerials();
protected:
GLsizei mWidth;
@ -65,26 +113,20 @@ class RenderbufferStorage
private:
DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
static unsigned int issueSerial();
const unsigned int mSerial;
static unsigned int mCurrentSerial;
};
// Renderbuffer implements the GL renderbuffer object.
// It's only a proxy for a RenderbufferStorage instance; the internal object
// It's only a proxy for a RenderbufferInterface instance; the internal object
// can change whenever glRenderbufferStorage is called.
class Renderbuffer : public RefCountObject
{
public:
Renderbuffer(GLuint id, RenderbufferStorage *storage);
Renderbuffer(GLuint id, RenderbufferInterface *storage);
~Renderbuffer();
bool isColorbuffer() const;
bool isDepthbuffer() const;
bool isStencilbuffer() const;
virtual ~Renderbuffer();
IDirect3DSurface9 *getRenderTarget();
IDirect3DSurface9 *getDepthStencil();
@ -104,40 +146,27 @@ class Renderbuffer : public RefCountObject
unsigned int getSerial() const;
void setStorage(RenderbufferStorage *newStorage);
RenderbufferStorage *getStorage() { return mStorage; }
private:
DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
RenderbufferStorage *mStorage;
RenderbufferInterface *mInstance;
};
class Colorbuffer : public RenderbufferStorage
{
public:
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
Colorbuffer(Texture *texture, GLenum target);
Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
virtual ~Colorbuffer();
virtual bool isColorbuffer() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
virtual GLenum getType() const;
virtual D3DFORMAT getD3DFormat() const;
private:
DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
IDirect3DSurface9 *mRenderTarget;
Texture *mTexture;
GLenum mTarget;
};
class DepthStencilbuffer : public RenderbufferStorage
@ -148,14 +177,13 @@ class DepthStencilbuffer : public RenderbufferStorage
~DepthStencilbuffer();
virtual bool isDepthbuffer() const;
virtual bool isStencilbuffer() const;
virtual IDirect3DSurface9 *getDepthStencil();
protected:
IDirect3DSurface9 *mDepthStencil;
private:
DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
IDirect3DSurface9 *mDepthStencil;
};
class Depthbuffer : public DepthStencilbuffer
@ -166,9 +194,6 @@ class Depthbuffer : public DepthStencilbuffer
virtual ~Depthbuffer();
virtual bool isDepthbuffer() const;
virtual bool isStencilbuffer() const;
private:
DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
};
@ -181,9 +206,6 @@ class Stencilbuffer : public DepthStencilbuffer
virtual ~Stencilbuffer();
virtual bool isDepthbuffer() const;
virtual bool isStencilbuffer() const;
private:
DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -43,6 +43,126 @@ enum
IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
};
class Image
{
public:
Image();
~Image();
bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease);
void markDirty() {mDirty = true;}
void markClean() {mDirty = false;}
HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
void unlock();
bool isRenderable() const;
D3DFORMAT getD3DFormat() const;
GLsizei getWidth() const {return mWidth;}
GLsizei getHeight() const {return mHeight;}
GLenum getFormat() const {return mFormat;}
GLenum getType() const {return mType;}
bool isDirty() const {return mSurface && mDirty;}
IDirect3DSurface9 *getSurface();
void setManagedSurface(IDirect3DSurface9 *surface);
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
void loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
private:
DISALLOW_COPY_AND_ASSIGN(Image);
void createSurface();
GLsizei mWidth;
GLsizei mHeight;
GLenum mFormat;
GLenum mType;
bool mDirty;
bool mManaged;
IDirect3DSurface9 *mSurface;
};
class TextureStorage
{
public:
explicit TextureStorage(bool renderable);
virtual ~TextureStorage();
bool isRenderable() const;
bool isManaged() const;
unsigned int getTextureSerial() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage);
const bool mRenderable;
const bool mManaged;
const unsigned int mTextureSerial;
static unsigned int issueTextureSerial();
static unsigned int mCurrentTextureSerial;
};
class Texture : public RefCountObject
{
public:
@ -56,11 +176,13 @@ class Texture : public RefCountObject
bool setMagFilter(GLenum filter);
bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
bool setUsage(GLenum usage);
GLenum getMinFilter() const;
GLenum getMagFilter() const;
GLenum getWrapS() const;
GLenum getWrapT() const;
GLenum getUsage() const;
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
@ -68,7 +190,7 @@ class Texture : public RefCountObject
virtual GLenum getType() const = 0;
virtual D3DFORMAT getD3DFormat() const = 0;
virtual bool isComplete() const = 0;
virtual bool isSamplerComplete() const = 0;
virtual bool isCompressed() const = 0;
IDirect3DBaseTexture9 *getTexture();
@ -77,43 +199,26 @@ class Texture : public RefCountObject
virtual void generateMipmaps() = 0;
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
bool isDirtyParameter() const;
bool isDirtyImage() const;
bool hasDirtyParameters() const;
bool hasDirtyImages() const;
void resetDirty();
unsigned int getSerial() const;
unsigned int getTextureSerial() const;
unsigned int getRenderTargetSerial(GLenum target) const;
bool isImmutable() const;
static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
protected:
friend class Colorbuffer;
// Helper structure representing a single image layer
struct Image
{
Image();
~Image();
bool isRenderable() const;
D3DFORMAT getD3DFormat() const;
GLsizei width;
GLsizei height;
GLenum format;
GLenum type;
bool dirty;
IDirect3DSurface9 *surface;
};
friend class RenderbufferTexture;
void setImage(GLint unpackAlignment, const void *pixels, Image *image);
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
void copyToImage(Image *image, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const;
GLint creationLevels(GLsizei size, GLint maxlevel) const;
GLint creationLevels(GLsizei width, GLsizei height) const;
GLint creationLevels(GLsizei size) const;
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual void createTexture() = 0;
@ -121,82 +226,46 @@ class Texture : public RefCountObject
virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
void createSurface(Image *image);
Blit *getBlitter();
int levelCount() const;
static Blit *getBlitter();
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
GLenum mMinFilter;
GLenum mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
bool mDirtyParameter;
bool mDirtyParameters;
GLenum mUsage;
bool mDirtyImage;
bool mDirtyImages;
bool mIsRenderable;
bool mImmutable;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output, D3DSURFACE_DESC *description) const;
virtual TextureStorage *getStorage() const = 0;
};
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteImageDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadCompressedImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT1ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT3ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadDXT5ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
int inputPitch, const void *input, size_t outputPitch, void *output) const;
class TextureStorage2D : public TextureStorage
{
public:
explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderable);
static unsigned int issueSerial();
virtual ~TextureStorage2D();
const unsigned int mSerial;
IDirect3DSurface9 *getSurfaceLevel(int level);
IDirect3DBaseTexture9 *getBaseTexture() const;
static unsigned int mCurrentSerial;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
IDirect3DTexture9 *mTexture;
const unsigned int mRenderTargetSerial;
};
class Texture2D : public Texture
@ -219,9 +288,10 @@ class Texture2D : public Texture
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
virtual bool isComplete() const;
virtual bool isSamplerComplete() const;
virtual bool isCompressed() const;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
@ -238,18 +308,40 @@ class Texture2D : public Texture
virtual void updateTexture();
virtual void convertToRenderTarget();
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual TextureStorage *getStorage() const;
void redefineTexture(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type, bool force);
bool isMipmapComplete() const;
void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
IDirect3DTexture9 *mTexture;
TextureStorage2D *mTexture;
egl::Surface *mSurface;
BindingPointer<Renderbuffer> mColorbufferProxy;
};
class TextureStorageCubeMap : public TextureStorage
{
public:
TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderable);
virtual ~TextureStorageCubeMap();
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level);
IDirect3DBaseTexture9 *getBaseTexture() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
IDirect3DCubeTexture9 *mTexture;
const unsigned int mFirstRenderTargetSerial;
};
class TextureCubeMap : public Texture
{
public:
@ -278,14 +370,17 @@ class TextureCubeMap : public Texture
void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void storage(GLsizei levels, GLenum internalformat, GLsizei size);
virtual bool isComplete() const;
virtual bool isSamplerComplete() const;
virtual bool isCompressed() const;
virtual void generateMipmaps();
virtual Renderbuffer *getRenderbuffer(GLenum target);
static unsigned int faceIndex(GLenum face);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
@ -294,22 +389,18 @@ class TextureCubeMap : public Texture
virtual void updateTexture();
virtual void convertToRenderTarget();
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants.
// Returns NULL if the call underlying Direct3D call fails.
IDirect3DSurface9 *getCubeMapSurface(GLenum face, unsigned int level);
static unsigned int faceIndex(GLenum face);
virtual TextureStorage *getStorage() const;
bool isCubeComplete() const;
bool isMipmapCubeComplete() const;
void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void redefineTexture(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void redefineImage(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
IDirect3DCubeTexture9 *mTexture;
TextureStorageCubeMap *mTexture;
BindingPointer<Renderbuffer> mFaceProxies[6];
};

Просмотреть файл

@ -29,6 +29,12 @@ namespace gl
{
unsigned int VertexBuffer::mCurrentSerial = 1;
int elementsInBuffer(const VertexAttribute &attribute, int size)
{
int stride = attribute.stride();
return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
}
VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
@ -137,7 +143,7 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
{
if (staticBuffer->size() == 0)
{
int totalCount = buffer->size() / attribs[i].stride();
int totalCount = elementsInBuffer(attribs[i], buffer->size());
staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
}
else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
@ -216,7 +222,7 @@ GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, Translat
if (streamOffset == -1)
{
// Convert the entire buffer
int totalCount = buffer->size() / attribs[i].stride();
int totalCount = elementsInBuffer(attribs[i], buffer->size());
int startIndex = attribs[i].mOffset / attribs[i].stride();
streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i]);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -155,6 +155,11 @@ EXPORTS
glSetFenceNV @156
glTestFenceNV @157
glGetTranslatedShaderSourceANGLE @159
glTexStorage2DEXT @160
glGetGraphicsResetStatusEXT @161
glReadnPixelsEXT @162
glGetnUniformfvEXT @163
glGetnUniformivEXT @164
; EGL dependencies
glCreateContext @144 NONAME

Просмотреть файл

@ -7,6 +7,7 @@
// main.cpp: DLL entry point and management of thread-local data.
#include "libGLESv2/main.h"
#include "libGLESv2/utilities.h"
#include "common/debug.h"
#include "libEGL/Surface.h"
@ -93,6 +94,16 @@ Context *getContext()
return current->context;
}
Context *getNonLostContext()
{
Context *context = getContext();
if (context && !context->isContextLost())
return context;
return NULL;
}
egl::Display *getDisplay()
{
Current *current = (Current*)TlsGetValue(currentTLS);
@ -106,6 +117,19 @@ IDirect3DDevice9 *getDevice()
return display->getDevice();
}
bool checkDeviceLost(HRESULT errorCode)
{
egl::Display *display = NULL;
if (isDeviceLostError(errorCode))
{
display = gl::getDisplay();
display->notifyDeviceLost();
return true;
}
return false;
}
}
// Records an error code

Просмотреть файл

@ -29,9 +29,12 @@ struct Current
void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface);
Context *getContext();
Context *getNonLostContext();
egl::Display *getDisplay();
IDirect3DDevice9 *getDevice();
bool checkDeviceLost(HRESULT errorCode);
}
void error(GLenum errorCode);

Просмотреть файл

@ -20,7 +20,8 @@
namespace gl
{
int UniformComponentCount(GLenum type)
// This is how much data the application expects for a uniform
int UniformExternalComponentCount(GLenum type)
{
switch (type)
{
@ -125,7 +126,7 @@ size_t UniformComponentSize(GLenum type)
{
switch(type)
{
case GL_BOOL: return sizeof(GLboolean);
case GL_BOOL: return sizeof(GLint);
case GL_FLOAT: return sizeof(GLfloat);
case GL_INT: return sizeof(GLint);
default: UNREACHABLE();
@ -134,11 +135,16 @@ size_t UniformComponentSize(GLenum type)
return 0;
}
size_t UniformTypeSize(GLenum type)
size_t UniformInternalSize(GLenum type)
{
return UniformComponentSize(UniformComponentType(type)) * UniformInternalComponentCount(type);
}
size_t UniformExternalSize(GLenum type)
{
return UniformComponentSize(UniformComponentType(type)) * UniformExternalComponentCount(type);
}
int VariableRowCount(GLenum type)
{
switch (type)
@ -374,6 +380,68 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
}
}
GLenum ExtractFormat(GLenum internalformat)
{
switch (internalformat)
{
case GL_RGB565: return GL_RGB;
case GL_RGBA4: return GL_RGBA;
case GL_RGB5_A1: return GL_RGBA;
case GL_RGB8_OES: return GL_RGB;
case GL_RGBA8_OES: return GL_RGBA;
case GL_LUMINANCE8_ALPHA8_EXT: return GL_LUMINANCE_ALPHA;
case GL_LUMINANCE8_EXT: return GL_LUMINANCE;
case GL_ALPHA8_EXT: return GL_ALPHA;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
case GL_RGBA32F_EXT: return GL_RGBA;
case GL_RGB32F_EXT: return GL_RGB;
case GL_ALPHA32F_EXT: return GL_ALPHA;
case GL_LUMINANCE32F_EXT: return GL_LUMINANCE;
case GL_LUMINANCE_ALPHA32F_EXT: return GL_LUMINANCE_ALPHA;
case GL_RGBA16F_EXT: return GL_RGBA;
case GL_RGB16F_EXT: return GL_RGB;
case GL_ALPHA16F_EXT: return GL_ALPHA;
case GL_LUMINANCE16F_EXT: return GL_LUMINANCE;
case GL_LUMINANCE_ALPHA16F_EXT: return GL_LUMINANCE_ALPHA;
case GL_BGRA8_EXT: return GL_BGRA_EXT;
default: return GL_NONE; // Unsupported
}
}
GLenum ExtractType(GLenum internalformat)
{
switch (internalformat)
{
case GL_RGB565: return GL_UNSIGNED_SHORT_5_6_5;
case GL_RGBA4: return GL_UNSIGNED_SHORT_4_4_4_4;
case GL_RGB5_A1: return GL_UNSIGNED_SHORT_5_5_5_1;
case GL_RGB8_OES: return GL_UNSIGNED_BYTE;
case GL_RGBA8_OES: return GL_UNSIGNED_BYTE;
case GL_LUMINANCE8_ALPHA8_EXT: return GL_UNSIGNED_BYTE;
case GL_LUMINANCE8_EXT: return GL_UNSIGNED_BYTE;
case GL_ALPHA8_EXT: return GL_UNSIGNED_BYTE;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GL_UNSIGNED_BYTE;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GL_UNSIGNED_BYTE;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return GL_UNSIGNED_BYTE;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return GL_UNSIGNED_BYTE;
case GL_RGBA32F_EXT: return GL_FLOAT;
case GL_RGB32F_EXT: return GL_FLOAT;
case GL_ALPHA32F_EXT: return GL_FLOAT;
case GL_LUMINANCE32F_EXT: return GL_FLOAT;
case GL_LUMINANCE_ALPHA32F_EXT: return GL_FLOAT;
case GL_RGBA16F_EXT: return GL_HALF_FLOAT_OES;
case GL_RGB16F_EXT: return GL_HALF_FLOAT_OES;
case GL_ALPHA16F_EXT: return GL_HALF_FLOAT_OES;
case GL_LUMINANCE16F_EXT: return GL_HALF_FLOAT_OES;
case GL_LUMINANCE_ALPHA16F_EXT: return GL_HALF_FLOAT_OES;
case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE;
default: return GL_NONE; // Unsupported
}
}
bool IsColorRenderable(GLenum internalformat)
{
switch (internalformat)
@ -853,6 +921,50 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat)
}
}
bool IsFloat32Format(D3DFORMAT surfaceFormat)
{
switch(surfaceFormat)
{
case D3DFMT_R16F:
case D3DFMT_G16R16F:
case D3DFMT_A16B16G16R16F:
return false;
case D3DFMT_R32F:
case D3DFMT_G32R32F:
case D3DFMT_A32B32G32R32F:
return true;
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
case D3DFMT_A1R5G5B5:
case D3DFMT_R5G6B5:
return false;
default: UNREACHABLE();
}
return false;
}
bool IsFloat16Format(D3DFORMAT surfaceFormat)
{
switch(surfaceFormat)
{
case D3DFMT_R16F:
case D3DFMT_G16R16F:
case D3DFMT_A16B16G16R16F:
return true;
case D3DFMT_R32F:
case D3DFMT_G32R32F:
case D3DFMT_A32B32G32R32F:
return false;
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
case D3DFMT_A1R5G5B5:
case D3DFMT_R5G6B5:
return false;
default: UNREACHABLE();
}
return false;
}
GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
{
if (type == D3DMULTISAMPLE_NONMASKABLE)

Просмотреть файл

@ -21,10 +21,11 @@ namespace gl
struct Color;
int UniformComponentCount(GLenum type);
int UniformExternalComponentCount(GLenum type);
int UniformInternalComponentCount(GLenum type);
GLenum UniformComponentType(GLenum type);
size_t UniformTypeSize(GLenum type);
size_t UniformInternalSize(GLenum type);
size_t UniformExternalSize(GLenum type);
int VariableRowCount(GLenum type);
int VariableColumnCount(GLenum type);
@ -38,6 +39,8 @@ bool IsCompressed(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
bool IsTextureTarget(GLenum target);
bool CheckTextureFormatType(GLenum format, GLenum type);
GLenum ExtractFormat(GLenum internalformat);
GLenum ExtractType(GLenum internalformat);
bool IsColorRenderable(GLenum internalformat);
bool IsDepthRenderable(GLenum internalformat);
@ -74,6 +77,8 @@ GLuint GetGreenSize(D3DFORMAT colorFormat);
GLuint GetBlueSize(D3DFORMAT colorFormat);
GLuint GetDepthSize(D3DFORMAT depthFormat);
GLuint GetStencilSize(D3DFORMAT stencilFormat);
bool IsFloat32Format(D3DFORMAT surfaceFormat);
bool IsFloat16Format(D3DFORMAT surfaceFormat);
GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
@ -85,4 +90,18 @@ GLenum ConvertDepthStencilFormat(D3DFORMAT format);
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
inline bool isDeviceLostError(HRESULT errorCode)
{
switch (errorCode)
{
case D3DERR_DRIVERINTERNALERROR:
case D3DERR_DEVICELOST:
case D3DERR_DEVICEHUNG:
case D3DERR_DEVICEREMOVED:
return true;
default:
return false;
}
};
#endif // LIBGLESV2_UTILITIES_H

Просмотреть файл

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше