зеркало из https://github.com/mozilla/pjs.git
Merge m-c to s-c
This commit is contained in:
Коммит
3c0bdfd3fb
|
@ -71,29 +71,5 @@ ifndef DISABLE_XFORMS_HOOKS
|
|||
SHARED_LIBRARY_LIBS += ../src/xforms/$(LIB_PREFIX)accessibility_xforms_s.$(LIB_SUFFIX)
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LIBS = \
|
||||
gkgfx \
|
||||
thebes \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += \
|
||||
oleaut32.lib \
|
||||
version.lib \
|
||||
ole32.lib \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -88,8 +88,6 @@ EXPORTS = \
|
|||
# we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
CFLAGS += $(MOZ_GTK2_CFLAGS)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2: */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
|
@ -53,6 +53,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
testAttrs("logAssertive", {"live" : "assertive"}, true);
|
||||
testAttrs("marquee", {"live" : "off"}, true);
|
||||
testAttrs("status", {"live" : "polite"}, true);
|
||||
testAttrs("tablist", {"live" : "polite"}, true);
|
||||
testAttrs("timer", {"live" : "off"}, true);
|
||||
|
||||
// container-live object attribute
|
||||
|
@ -62,6 +63,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
testAttrs("logAssertiveChild", {"container-live" : "assertive"}, true);
|
||||
testAttrs("marqueeChild", {"container-live" : "off"}, true);
|
||||
testAttrs("statusChild", {"container-live" : "polite"}, true);
|
||||
testAttrs("tablistChild", {"container-live" : "polite"}, true);
|
||||
testAttrs("timerChild", {"container-live" : "off"}, true);
|
||||
|
||||
// container-live-role object attribute
|
||||
|
@ -75,6 +77,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
testAttrs("logAssertiveChild", {"container-live-role" : "log"}, true);
|
||||
testAttrs("marqueeChild", {"container-live-role" : "marquee"}, true);
|
||||
testAttrs("statusChild", {"container-live-role" : "status"}, true);
|
||||
testAttrs("tablistChild", {"container-live-role" : "tablist"}, true);
|
||||
testAttrs("timerChild", {"container-live-role" : "timer"}, true);
|
||||
|
||||
// absent aria-label and aria-labelledby object attribute
|
||||
|
@ -120,7 +123,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
title="make HTML <output> accessible">
|
||||
Mozilla Bug 558036
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=663136"
|
||||
title="Add test coverage for tablist as implicit live region">
|
||||
Mozilla Bug 663136
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
|
@ -154,6 +161,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
<div id="logAssertive" role="log" aria-live="assertive">excuse <div id="logAssertiveChild">me</div></div>
|
||||
<div id="marquee" role="marquee">excuse <div id="marqueeChild">me</div></div>
|
||||
<div id="status" role="status">excuse <div id="statusChild">me</div></div>
|
||||
<div id="tablist" role="tablist">tablist <div id="tablistChild">tab</div></div>
|
||||
<div id="timer" role="timer">excuse <div id="timerChild">me</div></div>
|
||||
|
||||
<!-- aria-label[ledby] should not be an object attribute -->
|
||||
|
|
|
@ -6,6 +6,7 @@ function numClosedTabs()
|
|||
function isUndoCloseEnabled() {
|
||||
document.popupNode = gBrowser.tabs[0];
|
||||
TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
|
||||
TabContextMenu.contextTab = null;
|
||||
return !document.getElementById("context_undoCloseTab").disabled;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,12 +91,13 @@ function test() {
|
|||
function Disabled() {
|
||||
document.popupNode = gBrowser.selectedTab;
|
||||
TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
|
||||
let command = document.getElementById("Browser:BookmarkAllTabs");
|
||||
return command.hasAttribute("disabled") && command.getAttribute("disabled") === "true";
|
||||
TabContextMenu.contextTab = null;
|
||||
return document.getElementById("Browser:BookmarkAllTabs").getAttribute("disabled") == "true";
|
||||
}
|
||||
|
||||
function Hidden() {
|
||||
document.popupNode = gBrowser.selectedTab;
|
||||
TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
|
||||
TabContextMenu.contextTab = null;
|
||||
return document.getElementById("context_bookmarkAllTabs").hidden;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ function test() {
|
|||
|
||||
// Check the context menu with two tabs
|
||||
popup(origTab);
|
||||
is(TabContextMenu.contextTab, origTab, "TabContextMenu context is the original tab");
|
||||
is(document.getElementById("context_closeTab").disabled, false, "Close Tab is enabled");
|
||||
is(document.getElementById("context_reloadAllTabs").disabled, false, "Reload All Tabs is enabled");
|
||||
|
||||
|
@ -55,7 +54,6 @@ function test() {
|
|||
|
||||
// Check the context menu with one tab.
|
||||
popup(testTab);
|
||||
is(TabContextMenu.contextTab, testTab, "TabContextMenu context is the test tab");
|
||||
is(document.getElementById("context_closeTab").disabled, false, "Close Tab is enabled when more than one tab exists");
|
||||
is(document.getElementById("context_reloadAllTabs").disabled, true, "Reload All Tabs is disabled");
|
||||
|
||||
|
@ -67,7 +65,6 @@ function test() {
|
|||
|
||||
// Check the context menu on the unpinned visible tab
|
||||
popup(testTab);
|
||||
is(TabContextMenu.contextTab, testTab, "TabContextMenu context is again the test tab");
|
||||
is(document.getElementById("context_closeOtherTabs").disabled, true, "Close Other Tabs is disabled");
|
||||
|
||||
// Show all tabs
|
||||
|
@ -76,7 +73,6 @@ function test() {
|
|||
|
||||
// Check the context menu now
|
||||
popup(testTab);
|
||||
is(TabContextMenu.contextTab, testTab, "TabContextMenu context is yet again the test tab");
|
||||
is(document.getElementById("context_closeOtherTabs").disabled, false, "Close Other Tabs is enabled");
|
||||
|
||||
gBrowser.removeTab(testTab);
|
||||
|
@ -86,4 +82,6 @@ function test() {
|
|||
function popup(tab) {
|
||||
document.popupNode = tab;
|
||||
TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
|
||||
}
|
||||
is(TabContextMenu.contextTab, tab, "TabContextMenu context is the expected tab");
|
||||
TabContextMenu.contextTab = null;
|
||||
}
|
||||
|
|
|
@ -49,5 +49,7 @@ function test() {
|
|||
function popup(tab) {
|
||||
document.popupNode = tab;
|
||||
TabContextMenu.updateContextMenu(document.getElementById("tabContextMenu"));
|
||||
is(TabContextMenu.contextTab, tab, "TabContextMenu context is the expected tab");
|
||||
TabContextMenu.contextTab = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,6 +139,9 @@ function test() {
|
|||
testDragToCreateOrphan, testReAddingAfterRemoval];
|
||||
|
||||
let next = function () {
|
||||
if (win)
|
||||
win.close();
|
||||
|
||||
let test = tests.shift();
|
||||
|
||||
if (!test) {
|
||||
|
@ -146,15 +149,12 @@ function test() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (win)
|
||||
win.close();
|
||||
|
||||
TabView.firstUseExperienced = false;
|
||||
|
||||
let onLoad = function (newWin) {
|
||||
win = newWin;
|
||||
removeToolbarButton();
|
||||
}
|
||||
};
|
||||
|
||||
let onShow = function () {
|
||||
cw = win.TabView.getContentWindow();
|
||||
|
@ -167,13 +167,12 @@ function test() {
|
|||
assertToolbarButtonNotExists();
|
||||
test();
|
||||
}, cw);
|
||||
}
|
||||
};
|
||||
|
||||
newWindowWithTabView(onShow, onLoad);
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function () win && win.close());
|
||||
|
||||
next();
|
||||
}
|
||||
|
|
|
@ -79,15 +79,12 @@ function test() {
|
|||
// ----------
|
||||
function whenTabAttrModified(tab, callback) {
|
||||
let onModified = function (event) {
|
||||
if (tab === event.target) {
|
||||
container.removeEventListener('TabAttrModified', onModified, false);
|
||||
// we need executeSoon here because the tabItem also listens for the
|
||||
// onTabAttrModified event. so this is to make sure the tabItem logic
|
||||
// is executed before the test logic.
|
||||
executeSoon(callback);
|
||||
}
|
||||
tab.removeEventListener(event.type, onModified, false);
|
||||
// we need executeSoon here because the tabItem also listens for the
|
||||
// TabAttrModified event. so this is to make sure the tabItem logic
|
||||
// is executed before the test logic.
|
||||
executeSoon(callback);
|
||||
}
|
||||
|
||||
let container = gBrowser.tabContainer;
|
||||
container.addEventListener('TabAttrModified', onModified, false);
|
||||
tab.addEventListener("TabAttrModified", onModified, false);
|
||||
}
|
||||
|
|
|
@ -61,19 +61,6 @@ CPPSRCS = \
|
|||
nsChromeRegistryContent.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -189,6 +189,7 @@ PYUNITS := \
|
|||
unit-JarMaker.py \
|
||||
unit-buildlist.py \
|
||||
unit-expandlibs.py \
|
||||
unit-writemozinfo.py \
|
||||
$(NULL)
|
||||
|
||||
check:: check-python-modules check-jar-mn
|
||||
|
|
|
@ -557,10 +557,6 @@ else
|
|||
ELF_DYNSTR_GC = :
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
|
||||
OS_LIBS += $(MOZ_QT_LIBS)
|
||||
endif
|
||||
|
||||
ifndef CROSS_COMPILE
|
||||
ifdef USE_ELF_DYNSTR_GC
|
||||
ifdef MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import with_statement
|
||||
import unittest
|
||||
import os, sys, time, tempfile
|
||||
from StringIO import StringIO
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from writemozinfo import build_dict, write_json, JsonValue, jsonify
|
||||
|
||||
class TestBuildDict(unittest.TestCase):
|
||||
def testMissing(self):
|
||||
"""
|
||||
Test that missing required values raises.
|
||||
"""
|
||||
self.assertRaises(Exception, build_dict, {})
|
||||
self.assertRaises(Exception, build_dict, {'OS_TARGET':'foo'})
|
||||
self.assertRaises(Exception, build_dict, {'TARGET_CPU':'foo'})
|
||||
|
||||
def testWin(self):
|
||||
d = build_dict({'OS_TARGET':'WINNT',
|
||||
'TARGET_CPU':'i386'})
|
||||
self.assertEqual('win', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
def testLinux(self):
|
||||
d = build_dict({'OS_TARGET':'Linux',
|
||||
'TARGET_CPU':'i386'})
|
||||
self.assertEqual('linux', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
d = build_dict({'OS_TARGET':'Linux',
|
||||
'TARGET_CPU':'x86_64'})
|
||||
self.assertEqual('linux', d['os'])
|
||||
self.assertEqual('x86_64', d['processor'])
|
||||
self.assertEqual(64, d['bits'])
|
||||
|
||||
def testMac(self):
|
||||
d = build_dict({'OS_TARGET':'Darwin',
|
||||
'TARGET_CPU':'i386'})
|
||||
self.assertEqual('mac', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
d = build_dict({'OS_TARGET':'Darwin',
|
||||
'TARGET_CPU':'x86_64'})
|
||||
self.assertEqual('mac', d['os'])
|
||||
self.assertEqual('x86_64', d['processor'])
|
||||
self.assertEqual(64, d['bits'])
|
||||
|
||||
def testAndroid(self):
|
||||
d = build_dict({'OS_TARGET':'Android',
|
||||
'TARGET_CPU':'arm'})
|
||||
self.assertEqual('android', d['os'])
|
||||
self.assertEqual('arm', d['processor'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
def testX86(self):
|
||||
"""
|
||||
Test that various i?86 values => x86.
|
||||
"""
|
||||
d = build_dict({'OS_TARGET':'WINNT',
|
||||
'TARGET_CPU':'i486'})
|
||||
self.assertEqual('x86', d['processor'])
|
||||
|
||||
d = build_dict({'OS_TARGET':'WINNT',
|
||||
'TARGET_CPU':'i686'})
|
||||
self.assertEqual('x86', d['processor'])
|
||||
|
||||
def testARM(self):
|
||||
"""
|
||||
Test that all arm CPU architectures => arm.
|
||||
"""
|
||||
d = build_dict({'OS_TARGET':'Linux',
|
||||
'TARGET_CPU':'arm'})
|
||||
self.assertEqual('arm', d['processor'])
|
||||
|
||||
d = build_dict({'OS_TARGET':'Linux',
|
||||
'TARGET_CPU':'armv7'})
|
||||
self.assertEqual('arm', d['processor'])
|
||||
|
||||
def testUnknown(self):
|
||||
"""
|
||||
Test that unknown values pass through okay.
|
||||
"""
|
||||
d = build_dict({'OS_TARGET':'RandOS',
|
||||
'TARGET_CPU':'cptwo'})
|
||||
self.assertEqual("randos", d["os"])
|
||||
self.assertEqual("cptwo", d["processor"])
|
||||
# unknown CPUs should not get a bits value
|
||||
self.assertFalse("bits" in d)
|
||||
|
||||
def testDebug(self):
|
||||
"""
|
||||
Test that debug values are properly detected.
|
||||
"""
|
||||
d = build_dict({'OS_TARGET':'Linux',
|
||||
'TARGET_CPU':'i386'})
|
||||
self.assertEqual(False, d['debug'])
|
||||
|
||||
d = build_dict({'OS_TARGET':'Linux',
|
||||
'TARGET_CPU':'i386',
|
||||
'MOZ_DEBUG':'1'})
|
||||
self.assertEqual(True, d['debug'])
|
||||
|
||||
class TestJsonValue(unittest.TestCase):
|
||||
def testNone(self):
|
||||
self.assertEqual("null", repr(JsonValue(None)))
|
||||
|
||||
def testBool(self):
|
||||
self.assertEqual("true", repr(JsonValue(True)))
|
||||
self.assertEqual("false", repr(JsonValue(False)))
|
||||
|
||||
def testStr(self):
|
||||
self.assertEqual("'abc'", repr(JsonValue("abc")))
|
||||
|
||||
def testInt(self):
|
||||
self.assertEqual("100", repr(JsonValue(100)))
|
||||
|
||||
def testInvalid(self):
|
||||
self.assertRaises(Exception, JsonValue, unicode("abc"))
|
||||
self.assertRaises(Exception, JsonValue, 123.45)
|
||||
|
||||
def parse_json(j):
|
||||
"""
|
||||
Awful hack to parse a restricted subset of JSON strings into Python dicts.
|
||||
"""
|
||||
return eval(j, {'true':True,'false':False,'null':None})
|
||||
|
||||
class TestJsonify(unittest.TestCase):
|
||||
"""
|
||||
Test the jsonify function.
|
||||
"""
|
||||
def testBasic(self):
|
||||
"""
|
||||
Sanity check the set of accepted Python value types.
|
||||
"""
|
||||
j = parse_json(jsonify({'a':True,'b':False,'c':None,'d':100,'e':"abc"}))
|
||||
self.assertEquals(True, j['a'])
|
||||
self.assertEquals(False, j['b'])
|
||||
self.assertEquals(None, j['c'])
|
||||
self.assertEquals(100, j['d'])
|
||||
self.assertEquals("abc", j['e'])
|
||||
|
||||
class TestWriteJson(unittest.TestCase):
|
||||
"""
|
||||
Test the write_json function.
|
||||
"""
|
||||
def setUp(self):
|
||||
fd, self.f = tempfile.mkstemp()
|
||||
os.close(fd)
|
||||
|
||||
def tearDown(self):
|
||||
os.unlink(self.f)
|
||||
|
||||
def testBasic(self):
|
||||
"""
|
||||
Test that writing to a file produces correct output.
|
||||
"""
|
||||
write_json(self.f, env={'OS_TARGET':'WINNT',
|
||||
'TARGET_CPU':'i386'})
|
||||
with open(self.f) as f:
|
||||
d = parse_json(f.read())
|
||||
self.assertEqual('win', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
def testFileObj(self):
|
||||
"""
|
||||
Test that writing to a file-like object produces correct output.
|
||||
"""
|
||||
s = StringIO()
|
||||
write_json(s, env={'OS_TARGET':'WINNT',
|
||||
'TARGET_CPU':'i386'})
|
||||
d = parse_json(s.getvalue())
|
||||
self.assertEqual('win', d['os'])
|
||||
self.assertEqual('x86', d['processor'])
|
||||
self.assertEqual(32, d['bits'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# This script is run during configure, taking variables set in configure
|
||||
# and producing a JSON file that describes some portions of the build
|
||||
# configuration, such as the target OS and CPU.
|
||||
#
|
||||
# The output file is intended to be used as input to the mozinfo package.
|
||||
from __future__ import with_statement
|
||||
import os, re, sys
|
||||
|
||||
def build_dict(env=os.environ):
|
||||
"""
|
||||
Build a dict containing data about the build configuration from
|
||||
the environment.
|
||||
"""
|
||||
d = {}
|
||||
# Check that all required variables are present first.
|
||||
required = ["TARGET_CPU", "OS_TARGET"]
|
||||
missing = [r for r in required if r not in env]
|
||||
if missing:
|
||||
raise Exception("Missing required environment variables: " %
|
||||
', '.join(missing))
|
||||
# os
|
||||
o = env["OS_TARGET"]
|
||||
known_os = {"Linux": "linux",
|
||||
"WINNT": "win",
|
||||
"Darwin": "mac",
|
||||
"Android": "android"}
|
||||
if o in known_os:
|
||||
d["os"] = known_os[o]
|
||||
else:
|
||||
# Allow unknown values, just lowercase them.
|
||||
d["os"] = o.lower()
|
||||
|
||||
# processor
|
||||
p = env["TARGET_CPU"]
|
||||
# do some slight massaging for some values
|
||||
#TODO: retain specific values in case someone wants them?
|
||||
if p.startswith("arm"):
|
||||
p = "arm"
|
||||
elif re.match("i[3-9]86", p):
|
||||
p = "x86"
|
||||
d["processor"] = p
|
||||
# hardcoded list of 64-bit CPUs
|
||||
if p in ["x86_64", "ppc64"]:
|
||||
d["bits"] = 64
|
||||
# hardcoded list of known 32-bit CPUs
|
||||
elif p in ["x86", "arm", "ppc"]:
|
||||
d["bits"] = 32
|
||||
# other CPUs will wind up with unknown bits
|
||||
|
||||
# debug
|
||||
d["debug"] = 'MOZ_DEBUG' in env and env['MOZ_DEBUG'] == '1'
|
||||
return d
|
||||
|
||||
#TODO: replace this with the json module when Python >= 2.6 is a requirement.
|
||||
class JsonValue:
|
||||
"""
|
||||
A class to serialize Python values into JSON-compatible representations.
|
||||
"""
|
||||
def __init__(self, v):
|
||||
if v is not None and not (isinstance(v,str) or isinstance(v,bool) or isinstance(v,int)):
|
||||
raise Exception("Unhandled data type: %s" % type(v))
|
||||
self.v = v
|
||||
def __repr__(self):
|
||||
if self.v is None:
|
||||
return "null"
|
||||
if isinstance(self.v,bool):
|
||||
return str(self.v).lower()
|
||||
return repr(self.v)
|
||||
|
||||
def jsonify(d):
|
||||
"""
|
||||
Return a JSON string of the dict |d|. Only handles a subset of Python
|
||||
value types: bool, str, int, None.
|
||||
"""
|
||||
jd = {}
|
||||
for k, v in d.iteritems():
|
||||
jd[k] = JsonValue(v)
|
||||
return repr(jd)
|
||||
|
||||
def write_json(file, env=os.environ):
|
||||
"""
|
||||
Write JSON data about the configuration specified in |env|
|
||||
to |file|, which may be a filename or file-like object.
|
||||
See build_dict for information about what environment variables are used,
|
||||
and what keys are produced.
|
||||
"""
|
||||
s = jsonify(build_dict(env))
|
||||
if isinstance(file, basestring):
|
||||
with open(file, "w") as f:
|
||||
f.write(s)
|
||||
else:
|
||||
file.write(s)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
write_json(sys.argv[1] if len(sys.argv) > 1 else sys.stdout)
|
||||
except Exception, e:
|
||||
print >>sys.stderr, str(e)
|
||||
sys.exit(1)
|
13
configure.in
13
configure.in
|
@ -634,17 +634,14 @@ case "$target" in
|
|||
fi
|
||||
|
||||
_CC_SUITE=8
|
||||
CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
|
||||
AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
|
||||
AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
|
||||
elif test "$_CC_MAJOR_VERSION" = "15"; then
|
||||
_CC_SUITE=9
|
||||
CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
|
||||
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
|
||||
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
|
||||
elif test "$_CC_MAJOR_VERSION" = "16"; then
|
||||
_CC_SUITE=10
|
||||
CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
|
||||
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
|
||||
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
|
||||
else
|
||||
|
@ -9327,6 +9324,16 @@ mv -f config/autoconf.mk config/autoconf.mk.orig 2> /dev/null
|
|||
|
||||
AC_OUTPUT($MAKEFILES)
|
||||
|
||||
# Generate a JSON config file for unittest harnesses etc to read
|
||||
# build configuration details from in a standardized way.
|
||||
OS_TARGET=${OS_TARGET} TARGET_CPU=${TARGET_CPU} MOZ_DEBUG=${MOZ_DEBUG} \
|
||||
$PYTHON ${_topsrcdir}/config/writemozinfo.py ./mozinfo.json.tmp
|
||||
if cmp -s ./mozinfo.json.tmp ./mozinfo.json; then
|
||||
rm ./mozinfo.json.tmp
|
||||
else
|
||||
mv -f ./mozinfo.json.tmp ./mozinfo.json
|
||||
fi
|
||||
|
||||
dnl Prevent the regeneration of cairo-features.h forcing rebuilds of gfx stuff
|
||||
if test "$CAIRO_FEATURES_H"; then
|
||||
if cmp -s $CAIRO_FEATURES_H "$CAIRO_FEATURES_H".orig; then
|
||||
|
|
|
@ -3437,8 +3437,6 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
|
|||
gfxContextMatrixAutoSaveRestore autoMatrixSR(mThebes);
|
||||
|
||||
mThebes->Translate(gfxPoint(dx, dy));
|
||||
mThebes->SetPattern(pattern);
|
||||
DirtyAllStyles();
|
||||
|
||||
gfxRect clip(0, 0, dw, dh);
|
||||
|
||||
|
@ -3450,6 +3448,7 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
|
|||
|
||||
if (ctx) {
|
||||
CopyContext(ctx, mThebes);
|
||||
ctx->SetPattern(pattern);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->Clip(clip);
|
||||
ctx->Paint();
|
||||
|
@ -3458,6 +3457,9 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
|
|||
}
|
||||
}
|
||||
|
||||
mThebes->SetPattern(pattern);
|
||||
DirtyAllStyles();
|
||||
|
||||
PRBool doUseIntermediateSurface = NeedToUseIntermediateSurface();
|
||||
if (doUseIntermediateSurface) {
|
||||
gfxContextAutoSaveRestore autoSR(mThebes);
|
||||
|
|
|
@ -59,10 +59,5 @@ EXPORTS = \
|
|||
|
||||
SHARED_LIBRARY_LIBS = ../src/$(LIB_PREFIX)msgmork_s.$(LIB_SUFFIX)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -69,14 +69,6 @@ SHARED_LIBRARY_LIBS= \
|
|||
../shistory/src/$(LIB_PREFIX)shistory_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS= \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
|
@ -90,23 +82,4 @@ LOCAL_INCLUDES = \
|
|||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/uriloader/exthandler/mac
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(TK_LIBS) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME, shell32 ole32)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_DBUS
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_DBUS_LIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_PLATFORM_MAEMO
|
||||
EXTRA_DSO_LDOPTS += $(MOZ_PLATFORM_MAEMO_LIBS)
|
||||
endif
|
||||
|
|
|
@ -54,10 +54,6 @@ CPPSRCS = nsSHEntry.cpp \
|
|||
nsSHistory.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../../base
|
||||
|
|
|
@ -132,42 +132,12 @@ LOCAL_INCLUDES = \
|
|||
$(MOZ_CAIRO_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(filter WINNT Darwin,$(OS_ARCH)))
|
||||
EXTRA_DSO_LIBS += gkgfx
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_NECKO_UTIL_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/dom/dom-config.mk
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,version)
|
||||
endif
|
||||
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
|
||||
ifdef MOZ_ENABLE_GTK2
|
||||
EXTRA_DSO_LDOPTS += -lgtkxtbin $(XLDFLAGS) $(XT_LIBS) $(XLIBS) $(XEXT_LIBS) $(XCOMPOSITE_LIBS)
|
||||
endif #MOZ_ENABLE_GTK2
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
|
||||
EXTRA_DSO_LDOPTS += $(XEXT_LIBS) $(XCOMPOSITE_LIBS)
|
||||
endif
|
||||
|
||||
$(DIST)/bin/plugins:
|
||||
$(NSINSTALL) -D $@
|
||||
|
|
|
@ -54,10 +54,6 @@ CPPSRCS = \
|
|||
nsGeoPosition.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
-I$(topsrcdir)/dom/ipc \
|
||||
|
|
|
@ -63,11 +63,6 @@ LOCAL_INCLUDES += \
|
|||
-I$(topsrcdir)/dom/base \
|
||||
-I$(topsrcdir)/netwerk/base/src \
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifdef BUILD_DEBUG_GC
|
||||
DEFINES += -DDEBUG_GC
|
||||
endif
|
||||
|
|
|
@ -52,10 +52,6 @@ CPPSRCS = \
|
|||
nsDesktopNotification.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
-I$(topsrcdir)/dom/ipc \
|
||||
|
|
|
@ -61,10 +61,6 @@ CPPSRCS = \
|
|||
nsEditorSpellCheck.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I../../libeditor/base/src
|
||||
|
|
|
@ -58,9 +58,5 @@ CPPSRCS = \
|
|||
nsTransactionStack.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -54,11 +54,5 @@ CPPSRCS = \
|
|||
nsTextServicesDocument.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ GRE_MODULE = 1
|
|||
LIBXUL_LIBRARY = 1
|
||||
|
||||
|
||||
EXTRA_DSO_LIBS = gkgfx thebes
|
||||
|
||||
CPPSRCS = \
|
||||
nsWebBrowserModule.cpp \
|
||||
$(NULL)
|
||||
|
@ -62,17 +60,6 @@ SHARED_LIBRARY_LIBS= \
|
|||
../webBrowser/$(LIB_PREFIX)nsWebBrowser_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS= \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += \
|
||||
|
|
|
@ -86,27 +86,10 @@ endif
|
|||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../printingui/src/win
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,winspool comdlg32)
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../printingui/src/mac
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LIBS = gkgfx
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(TK_LIBS) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -55,11 +55,6 @@ CPPSRCS = \
|
|||
nsPrintDialogUtil.cpp \
|
||||
$(NULL)
|
||||
|
||||
OS_LIBS += \
|
||||
comdlg32.lib \
|
||||
winspool.lib \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
|
|
@ -58,15 +58,9 @@ LIBXUL_LIBRARY = 1
|
|||
CPPSRCS = \
|
||||
nsAuthFactory.cpp \
|
||||
nsHttpNegotiateAuth.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS += \
|
||||
nsAuthGSSAPI.cpp \
|
||||
nsAuthSASL.cpp
|
||||
nsAuthSASL.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
LOCAL_INCLUDES += -DUSE_SSPI
|
||||
|
|
|
@ -65,10 +65,6 @@ XPIDLSRCS = \
|
|||
nsICookiePromptService.idl \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_MAIL_NEWS
|
||||
DEFINES += -DMOZ_MAIL_NEWS
|
||||
endif
|
||||
|
|
|
@ -55,8 +55,4 @@ CPPSRCS = \
|
|||
nsContentBlocker.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -65,13 +65,6 @@ DEFINES += -DMOZ_LDAP_XPCOM
|
|||
CPPSRCS += nsLDAPSyncQuery.cpp
|
||||
endif
|
||||
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
AUTOCFG_JS_EXPORTS = \
|
||||
$(srcdir)/prefcalls.js \
|
||||
$(NULL)
|
||||
|
|
|
@ -55,11 +55,6 @@ ifdef MOZ_ENABLE_GTK2
|
|||
DIRS = gconf
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
-L$(DIST)/bin \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsSystemPref.cpp \
|
||||
$(NULL)
|
||||
|
|
|
@ -54,12 +54,6 @@ CPPSRCS = \
|
|||
|
||||
SHARED_LIBRARY_LIBS = ../libsystem-pref_s.a
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
-L$(DIST)/bin \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(MOZ_GTK2_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsSystemPrefModule
|
||||
|
|
|
@ -67,14 +67,6 @@ CPPSRCS += affentry.cpp \
|
|||
DEFINES = -DHUNSPELL_STATIC
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(XPCOM_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_HUNSPELL_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef MOZ_NATIVE_HUNSPELL
|
||||
|
|
|
@ -65,13 +65,6 @@ CPPSRCS = \
|
|||
SHARED_LIBRARY_LIBS += ../hunspell/src/$(LIB_PREFIX)hunspell_s.$(LIB_SUFFIX)
|
||||
LOCAL_INCLUDES += -I$(srcdir)/../hunspell/src
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(LIBS_DIR) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_HUNSPELL_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
|
|
|
@ -64,8 +64,4 @@ SHARED_LIBRARY_LIBS = \
|
|||
../base/$(LIB_PREFIX)universalchardet_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -66,7 +66,6 @@ VPATH += $(srcdir)/..
|
|||
VPATH += $(srcdir)/../compiler
|
||||
VPATH += $(srcdir)/../compiler/preprocessor
|
||||
VPATH += $(srcdir)/../common
|
||||
VPATH += $(srcdir)/geometry
|
||||
|
||||
# Translator/compiler first
|
||||
|
||||
|
@ -128,8 +127,6 @@ endif
|
|||
|
||||
CPPSRCS += \
|
||||
debug.cpp \
|
||||
IndexDataManager.cpp \
|
||||
VertexDataManager.cpp \
|
||||
Blit.cpp \
|
||||
Buffer.cpp \
|
||||
Context.cpp \
|
||||
|
|
|
@ -1,382 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/IndexDataManager.cpp: Defines the IndexDataManager, a class that
|
||||
// runs the Buffer translation process for index buffers.
|
||||
|
||||
#include "libGLESv2/geometry/IndexDataManager.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include "libGLESv2/Buffer.h"
|
||||
#include "libGLESv2/mathutil.h"
|
||||
#include "libGLESv2/main.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device)
|
||||
{
|
||||
mStreamingBufferShort = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
|
||||
|
||||
if (context->supports32bitIndices())
|
||||
{
|
||||
mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
|
||||
}
|
||||
else
|
||||
{
|
||||
mStreamingBufferInt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IndexDataManager::~IndexDataManager()
|
||||
{
|
||||
delete mStreamingBufferShort;
|
||||
delete mStreamingBufferInt;
|
||||
}
|
||||
|
||||
void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
|
||||
{
|
||||
if (type == GL_UNSIGNED_BYTE)
|
||||
{
|
||||
const GLubyte *in = static_cast<const GLubyte*>(input);
|
||||
GLushort *out = static_cast<GLushort*>(output);
|
||||
|
||||
for (GLsizei i = 0; i < count; i++)
|
||||
{
|
||||
out[i] = in[i];
|
||||
}
|
||||
}
|
||||
else if (type == GL_UNSIGNED_INT)
|
||||
{
|
||||
memcpy(output, input, count * sizeof(GLuint));
|
||||
}
|
||||
else if (type == GL_UNSIGNED_SHORT)
|
||||
{
|
||||
memcpy(output, input, count * sizeof(GLushort));
|
||||
}
|
||||
else UNREACHABLE();
|
||||
}
|
||||
|
||||
template <class IndexType>
|
||||
void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
|
||||
{
|
||||
*minIndex = indices[0];
|
||||
*maxIndex = indices[0];
|
||||
|
||||
for (GLsizei i = 0; i < count; i++)
|
||||
{
|
||||
if (*minIndex > indices[i]) *minIndex = indices[i];
|
||||
if (*maxIndex < indices[i]) *maxIndex = indices[i];
|
||||
}
|
||||
}
|
||||
|
||||
void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
|
||||
{
|
||||
if (type == GL_UNSIGNED_BYTE)
|
||||
{
|
||||
computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
|
||||
}
|
||||
else if (type == GL_UNSIGNED_INT)
|
||||
{
|
||||
computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
|
||||
}
|
||||
else if (type == GL_UNSIGNED_SHORT)
|
||||
{
|
||||
computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
|
||||
}
|
||||
else UNREACHABLE();
|
||||
}
|
||||
|
||||
GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
|
||||
{
|
||||
D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
|
||||
intptr_t offset = reinterpret_cast<intptr_t>(indices);
|
||||
bool alignedOffset = false;
|
||||
|
||||
if (buffer != NULL)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
|
||||
case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
|
||||
case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
|
||||
default: UNREACHABLE(); alignedOffset = false;
|
||||
}
|
||||
|
||||
if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
|
||||
{
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
indices = static_cast<const GLubyte*>(buffer->data()) + offset;
|
||||
}
|
||||
|
||||
StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
|
||||
|
||||
StaticIndexBuffer *staticBuffer = buffer ? buffer->getIndexBuffer() : NULL;
|
||||
IndexBuffer *indexBuffer = streamingBuffer;
|
||||
UINT streamOffset = 0;
|
||||
|
||||
if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
|
||||
{
|
||||
indexBuffer = staticBuffer;
|
||||
streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
|
||||
|
||||
if (streamOffset == -1)
|
||||
{
|
||||
streamOffset = (offset / typeSize(type)) * indexSize(format);
|
||||
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
|
||||
staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int convertCount = count;
|
||||
|
||||
if (staticBuffer)
|
||||
{
|
||||
if (staticBuffer->size() == 0 && alignedOffset)
|
||||
{
|
||||
indexBuffer = staticBuffer;
|
||||
convertCount = buffer->size() / typeSize(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->invalidateStaticData();
|
||||
staticBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *output = NULL;
|
||||
|
||||
if (indexBuffer)
|
||||
{
|
||||
indexBuffer->reserveSpace(convertCount * indexSize(format), type);
|
||||
output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
|
||||
}
|
||||
|
||||
if (output == NULL)
|
||||
{
|
||||
ERR("Failed to map index buffer.");
|
||||
return GL_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
|
||||
indexBuffer->unmap();
|
||||
|
||||
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
|
||||
|
||||
if (staticBuffer)
|
||||
{
|
||||
streamOffset = (offset / typeSize(type)) * indexSize(format);
|
||||
staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
|
||||
}
|
||||
}
|
||||
|
||||
translated->indexBuffer = indexBuffer->getBuffer();
|
||||
translated->startIndex = streamOffset / indexSize(format);
|
||||
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
|
||||
{
|
||||
return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short);
|
||||
}
|
||||
|
||||
std::size_t IndexDataManager::typeSize(GLenum type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_UNSIGNED_INT: return sizeof(GLuint);
|
||||
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
|
||||
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
|
||||
default: UNREACHABLE(); return sizeof(GLushort);
|
||||
}
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
|
||||
HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating an index buffer of size %lu.", size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
if (mIndexBuffer)
|
||||
{
|
||||
mIndexBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
|
||||
{
|
||||
return mIndexBuffer;
|
||||
}
|
||||
|
||||
void IndexBuffer::unmap()
|
||||
{
|
||||
if (mIndexBuffer)
|
||||
{
|
||||
mIndexBuffer->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
StreamingIndexBuffer::StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format) : IndexBuffer(device, initialSize, format)
|
||||
{
|
||||
mWritePosition = 0;
|
||||
}
|
||||
|
||||
StreamingIndexBuffer::~StreamingIndexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset)
|
||||
{
|
||||
void *mapPtr = NULL;
|
||||
|
||||
if (mIndexBuffer)
|
||||
{
|
||||
HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*offset = mWritePosition;
|
||||
mWritePosition += requiredSpace;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
|
||||
{
|
||||
if (requiredSpace > mBufferSize)
|
||||
{
|
||||
if (mIndexBuffer)
|
||||
{
|
||||
mIndexBuffer->Release();
|
||||
mIndexBuffer = NULL;
|
||||
}
|
||||
|
||||
mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
|
||||
|
||||
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
|
||||
HRESULT result = mDevice->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
|
||||
}
|
||||
|
||||
mWritePosition = 0;
|
||||
}
|
||||
else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
|
||||
{
|
||||
void *dummy;
|
||||
mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
|
||||
mIndexBuffer->Unlock();
|
||||
|
||||
mWritePosition = 0;
|
||||
}
|
||||
}
|
||||
|
||||
StaticIndexBuffer::StaticIndexBuffer(IDirect3DDevice9 *device) : IndexBuffer(device, 0, D3DFMT_UNKNOWN)
|
||||
{
|
||||
mCacheType = GL_NONE;
|
||||
}
|
||||
|
||||
StaticIndexBuffer::~StaticIndexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void *StaticIndexBuffer::map(UINT requiredSpace, UINT *offset)
|
||||
{
|
||||
void *mapPtr = NULL;
|
||||
|
||||
if (mIndexBuffer)
|
||||
{
|
||||
HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*offset = 0;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
|
||||
{
|
||||
if (!mIndexBuffer && mBufferSize == 0)
|
||||
{
|
||||
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
|
||||
HRESULT result = mDevice->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
|
||||
}
|
||||
|
||||
mBufferSize = requiredSpace;
|
||||
mCacheType = type;
|
||||
}
|
||||
else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
|
||||
{
|
||||
// Already allocated
|
||||
}
|
||||
else UNREACHABLE(); // Static index buffers can't be resized
|
||||
}
|
||||
|
||||
bool StaticIndexBuffer::lookupType(GLenum type)
|
||||
{
|
||||
return mCacheType == type;
|
||||
}
|
||||
|
||||
UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
|
||||
{
|
||||
for (unsigned int range = 0; range < mCache.size(); range++)
|
||||
{
|
||||
if (mCache[range].offset == offset && mCache[range].count == count)
|
||||
{
|
||||
*minIndex = mCache[range].minIndex;
|
||||
*maxIndex = mCache[range].maxIndex;
|
||||
|
||||
return mCache[range].streamOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
|
||||
{
|
||||
IndexRange indexRange = {offset, count, minIndex, maxIndex, streamOffset};
|
||||
mCache.push_back(indexRange);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/IndexDataManager.h: Defines the IndexDataManager, a class that
|
||||
// runs the Buffer translation process for index buffers.
|
||||
|
||||
#ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
|
||||
#define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "libGLESv2/Context.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
struct TranslatedIndexData
|
||||
{
|
||||
UINT minIndex;
|
||||
UINT maxIndex;
|
||||
UINT startIndex;
|
||||
|
||||
IDirect3DIndexBuffer9 *indexBuffer;
|
||||
};
|
||||
|
||||
class IndexBuffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
UINT size() const { return mBufferSize; }
|
||||
virtual void *map(UINT requiredSpace, UINT *offset) = 0;
|
||||
void unmap();
|
||||
virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0;
|
||||
|
||||
IDirect3DIndexBuffer9 *getBuffer() const;
|
||||
|
||||
protected:
|
||||
IDirect3DDevice9 *const mDevice;
|
||||
|
||||
IDirect3DIndexBuffer9 *mIndexBuffer;
|
||||
UINT mBufferSize;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
|
||||
};
|
||||
|
||||
class StreamingIndexBuffer : public IndexBuffer
|
||||
{
|
||||
public:
|
||||
StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format);
|
||||
~StreamingIndexBuffer();
|
||||
|
||||
void *map(UINT requiredSpace, UINT *offset);
|
||||
void reserveSpace(UINT requiredSpace, GLenum type);
|
||||
|
||||
private:
|
||||
UINT mWritePosition;
|
||||
};
|
||||
|
||||
class StaticIndexBuffer : public IndexBuffer
|
||||
{
|
||||
public:
|
||||
explicit StaticIndexBuffer(IDirect3DDevice9 *device);
|
||||
~StaticIndexBuffer();
|
||||
|
||||
void *map(UINT requiredSpace, UINT *offset);
|
||||
void reserveSpace(UINT requiredSpace, GLenum type);
|
||||
|
||||
bool lookupType(GLenum type);
|
||||
UINT lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex); // Returns the offset into the index buffer, or -1 if not found
|
||||
void addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset);
|
||||
|
||||
private:
|
||||
GLenum mCacheType;
|
||||
|
||||
struct IndexRange
|
||||
{
|
||||
intptr_t offset;
|
||||
GLsizei count;
|
||||
|
||||
UINT minIndex;
|
||||
UINT maxIndex;
|
||||
UINT streamOffset;
|
||||
};
|
||||
|
||||
std::vector<IndexRange> mCache;
|
||||
};
|
||||
|
||||
class IndexDataManager
|
||||
{
|
||||
public:
|
||||
IndexDataManager(Context *context, IDirect3DDevice9 *evice);
|
||||
virtual ~IndexDataManager();
|
||||
|
||||
GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
|
||||
|
||||
std::size_t typeSize(GLenum type) const;
|
||||
std::size_t indexSize(D3DFORMAT format) const;
|
||||
|
||||
IDirect3DDevice9 *const mDevice;
|
||||
|
||||
StreamingIndexBuffer *mStreamingBufferShort;
|
||||
StreamingIndexBuffer *mStreamingBufferInt;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
|
|
@ -1,769 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/VertexDataManager.h: Defines the VertexDataManager, a class that
|
||||
// runs the Buffer translation process.
|
||||
|
||||
#include "libGLESv2/geometry/VertexDataManager.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include "libGLESv2/Buffer.h"
|
||||
#include "libGLESv2/Program.h"
|
||||
#include "libGLESv2/main.h"
|
||||
|
||||
#include "libGLESv2/geometry/vertexconversion.h"
|
||||
#include "libGLESv2/geometry/IndexDataManager.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
|
||||
{
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
mDirtyCurrentValue[i] = true;
|
||||
mCurrentValueBuffer[i] = NULL;
|
||||
}
|
||||
|
||||
const D3DCAPS9 &caps = context->getDeviceCaps();
|
||||
checkVertexCaps(caps.DeclTypes);
|
||||
|
||||
mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
VertexDataManager::~VertexDataManager()
|
||||
{
|
||||
delete mStreamingBuffer;
|
||||
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
delete mCurrentValueBuffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
|
||||
{
|
||||
Buffer *buffer = attribute.mBoundBuffer.get();
|
||||
|
||||
int inputStride = attribute.stride();
|
||||
int elementSize = attribute.typeSize();
|
||||
const FormatConverter &converter = formatConverter(attribute);
|
||||
UINT streamOffset = 0;
|
||||
|
||||
void *output = NULL;
|
||||
|
||||
if (vertexBuffer)
|
||||
{
|
||||
output = vertexBuffer->map(attribute, spaceRequired(attribute, count), &streamOffset);
|
||||
}
|
||||
|
||||
if (output == NULL)
|
||||
{
|
||||
ERR("Failed to map vertex buffer.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *input = NULL;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
int offset = attribute.mOffset;
|
||||
|
||||
input = static_cast<const char*>(buffer->data()) + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
input = static_cast<const char*>(attribute.mPointer);
|
||||
}
|
||||
|
||||
input += inputStride * start;
|
||||
|
||||
if (converter.identity && inputStride == elementSize)
|
||||
{
|
||||
memcpy(output, input, count * inputStride);
|
||||
}
|
||||
else
|
||||
{
|
||||
converter.convertArray(input, inputStride, count, output);
|
||||
}
|
||||
|
||||
vertexBuffer->unmap();
|
||||
|
||||
return streamOffset;
|
||||
}
|
||||
|
||||
GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
|
||||
{
|
||||
GLenum error = GL_NO_ERROR;
|
||||
const VertexAttributeArray &attribs = mContext->getVertexAttributes();
|
||||
Program *program = mContext->getCurrentProgram();
|
||||
|
||||
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
|
||||
{
|
||||
translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1);
|
||||
}
|
||||
|
||||
// Determine the required storage size per used buffer
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
Buffer *buffer = attribs[i].mBoundBuffer.get();
|
||||
|
||||
if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
|
||||
{
|
||||
StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
|
||||
|
||||
if (staticBuffer && staticBuffer->size() == 0)
|
||||
{
|
||||
int totalCount = buffer->size() / attribs[i].stride();
|
||||
staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
|
||||
}
|
||||
else if (!staticBuffer || staticBuffer->lookupAttribute(attribs[i]) == -1)
|
||||
{
|
||||
if (mStreamingBuffer)
|
||||
{
|
||||
mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate static buffers if the attribute formats no longer match
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
Buffer *buffer = attribs[i].mBoundBuffer.get();
|
||||
|
||||
if (translated[i].active && attribs[i].mArrayEnabled && buffer)
|
||||
{
|
||||
StaticVertexBuffer *staticBuffer = buffer->getVertexBuffer();
|
||||
|
||||
if (staticBuffer && staticBuffer->size() != 0)
|
||||
{
|
||||
bool matchingAttributes = true;
|
||||
|
||||
for (int j = 0; j < MAX_VERTEX_ATTRIBS; j++)
|
||||
{
|
||||
if (translated[j].active && attribs[j].mArrayEnabled && attribs[j].mBoundBuffer.get() == buffer)
|
||||
{
|
||||
if (staticBuffer->lookupAttribute(attribs[j]) == -1)
|
||||
{
|
||||
matchingAttributes = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!matchingAttributes && mStreamingBuffer)
|
||||
{
|
||||
mStreamingBuffer->addRequiredSpaceFor(staticBuffer);
|
||||
buffer->invalidateStaticData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve the required space per used buffer
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
Buffer *buffer = attribs[i].mBoundBuffer.get();
|
||||
|
||||
if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
|
||||
{
|
||||
ArrayVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
|
||||
ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer;
|
||||
|
||||
if (vertexBuffer)
|
||||
{
|
||||
vertexBuffer->reserveRequiredSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the vertex data translations
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
if (translated[i].active)
|
||||
{
|
||||
Buffer *buffer = attribs[i].mBoundBuffer.get();
|
||||
|
||||
if (attribs[i].mArrayEnabled)
|
||||
{
|
||||
if (!buffer && attribs[i].mPointer == NULL)
|
||||
{
|
||||
// This is an application error that would normally result in a crash, but we catch it and return an error
|
||||
ERR("An enabled vertex array has no buffer and no pointer.");
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
const FormatConverter &converter = formatConverter(attribs[i]);
|
||||
|
||||
StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
|
||||
ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer);
|
||||
|
||||
UINT streamOffset = -1;
|
||||
|
||||
if (staticBuffer)
|
||||
{
|
||||
streamOffset = staticBuffer->lookupAttribute(attribs[i]);
|
||||
|
||||
if (streamOffset == -1)
|
||||
{
|
||||
// Convert the entire buffer
|
||||
int totalCount = buffer->size() / attribs[i].stride();
|
||||
int startIndex = attribs[i].mOffset / attribs[i].stride();
|
||||
|
||||
streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i]);
|
||||
}
|
||||
|
||||
if (streamOffset != -1)
|
||||
{
|
||||
streamOffset += (start + attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
|
||||
}
|
||||
|
||||
if (streamOffset == -1)
|
||||
{
|
||||
return GL_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
translated[i].vertexBuffer = vertexBuffer->getBuffer();
|
||||
translated[i].type = converter.d3dDeclType;
|
||||
translated[i].stride = converter.outputElementSize;
|
||||
translated[i].offset = streamOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mDirtyCurrentValue[i])
|
||||
{
|
||||
delete mCurrentValueBuffer[i];
|
||||
mCurrentValueBuffer[i] = new ConstantVertexBuffer(mDevice, attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
|
||||
mDirtyCurrentValue[i] = false;
|
||||
}
|
||||
|
||||
translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
|
||||
|
||||
translated[i].type = D3DDECLTYPE_FLOAT4;
|
||||
translated[i].stride = 0;
|
||||
translated[i].offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count) const
|
||||
{
|
||||
return formatConverter(attrib).outputElementSize * count;
|
||||
}
|
||||
|
||||
// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
|
||||
//
|
||||
// BYTE SHORT (Cast)
|
||||
// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
|
||||
// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast)
|
||||
// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize)
|
||||
// SHORT SHORT (Identity)
|
||||
// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize)
|
||||
// UNSIGNED_SHORT FLOAT (Cast)
|
||||
// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize)
|
||||
// FIXED (not in WebGL) FLOAT (FixedToFloat)
|
||||
// FLOAT FLOAT (Identity)
|
||||
|
||||
// GLToCType maps from GL type (as GLenum) to the C typedef.
|
||||
template <GLenum GLType> struct GLToCType { };
|
||||
|
||||
template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
|
||||
template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
|
||||
template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
|
||||
template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
|
||||
template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
|
||||
template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
|
||||
|
||||
// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
|
||||
enum D3DVertexType
|
||||
{
|
||||
D3DVT_FLOAT,
|
||||
D3DVT_SHORT,
|
||||
D3DVT_SHORT_NORM,
|
||||
D3DVT_UBYTE,
|
||||
D3DVT_UBYTE_NORM,
|
||||
D3DVT_USHORT_NORM
|
||||
};
|
||||
|
||||
// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
|
||||
template <unsigned int D3DType> struct D3DToCType { };
|
||||
|
||||
template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
|
||||
template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
|
||||
template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
|
||||
template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
|
||||
template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
|
||||
template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
|
||||
|
||||
// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
|
||||
template <unsigned int type, int size>
|
||||
struct WidenRule
|
||||
{
|
||||
};
|
||||
|
||||
template <int size> struct WidenRule<D3DVT_FLOAT, size> : gl::NoWiden<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_SHORT, size> : gl::WidenToEven<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : gl::WidenToEven<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_UBYTE, size> : gl::WidenToFour<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : gl::WidenToFour<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : gl::WidenToEven<size> { };
|
||||
|
||||
// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
|
||||
template <unsigned int d3dtype, int size>
|
||||
struct VertexTypeFlags
|
||||
{
|
||||
};
|
||||
|
||||
template <unsigned int capflag, unsigned int declflag>
|
||||
struct VertexTypeFlagsHelper
|
||||
{
|
||||
enum { capflag = capflag };
|
||||
enum { declflag = declflag };
|
||||
};
|
||||
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
|
||||
|
||||
|
||||
// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
|
||||
template <GLenum GLtype, bool normalized>
|
||||
struct VertexTypeMapping
|
||||
{
|
||||
};
|
||||
|
||||
template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
|
||||
struct VertexTypeMappingBase
|
||||
{
|
||||
enum { preferred = Preferred };
|
||||
enum { fallback = Fallback };
|
||||
};
|
||||
|
||||
template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast
|
||||
template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize
|
||||
template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity
|
||||
template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
|
||||
template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat
|
||||
template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity
|
||||
|
||||
|
||||
// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
|
||||
// The conversion rules themselves are defined in vertexconversion.h.
|
||||
|
||||
// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
|
||||
template <GLenum fromType, bool normalized, unsigned int toType>
|
||||
struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
|
||||
{
|
||||
};
|
||||
|
||||
// All conversions from normalized types to float use the Normalize operator.
|
||||
template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { };
|
||||
|
||||
// Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules.
|
||||
template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
|
||||
template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
|
||||
|
||||
// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
|
||||
// whether it is normalized or not.
|
||||
template <class T, bool normalized>
|
||||
struct DefaultVertexValuesStage2
|
||||
{
|
||||
};
|
||||
|
||||
template <class T> struct DefaultVertexValuesStage2<T, true> : gl::NormalizedDefaultValues<T> { };
|
||||
template <class T> struct DefaultVertexValuesStage2<T, false> : gl::SimpleDefaultValues<T> { };
|
||||
|
||||
// Work out the default value rule for a D3D type (expressed as the C type) and
|
||||
template <class T, bool normalized>
|
||||
struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
|
||||
{
|
||||
};
|
||||
|
||||
template <bool normalized> struct DefaultVertexValues<float, normalized> : gl::SimpleDefaultValues<float> { };
|
||||
|
||||
// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
|
||||
// The fallback conversion produces an output that all D3D9 devices must support.
|
||||
template <class T> struct UsePreferred { enum { type = T::preferred }; };
|
||||
template <class T> struct UseFallback { enum { type = T::fallback }; };
|
||||
|
||||
// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
|
||||
// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
|
||||
// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
|
||||
template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
|
||||
struct Converter
|
||||
: gl::VertexDataConverter<typename GLToCType<fromType>::type,
|
||||
WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
|
||||
ConversionRule<fromType,
|
||||
normalized,
|
||||
PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
|
||||
DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
|
||||
{
|
||||
private:
|
||||
enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
|
||||
enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
|
||||
|
||||
public:
|
||||
enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
|
||||
enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
|
||||
};
|
||||
|
||||
// Initialise a TranslationInfo
|
||||
#define TRANSLATION(type, norm, size, preferred) \
|
||||
{ \
|
||||
Converter<type, norm, size, preferred>::identity, \
|
||||
Converter<type, norm, size, preferred>::finalSize, \
|
||||
Converter<type, norm, size, preferred>::convertArray, \
|
||||
static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
|
||||
}
|
||||
|
||||
#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
|
||||
{ \
|
||||
Converter<type, norm, size, UsePreferred>::capflag, \
|
||||
TRANSLATION(type, norm, size, UsePreferred), \
|
||||
TRANSLATION(type, norm, size, UseFallback) \
|
||||
}
|
||||
|
||||
#define TRANSLATIONS_FOR_TYPE(type) \
|
||||
{ \
|
||||
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
|
||||
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \
|
||||
}
|
||||
|
||||
const VertexDataManager::TranslationDescription VertexDataManager::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
|
||||
{
|
||||
TRANSLATIONS_FOR_TYPE(GL_BYTE),
|
||||
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
|
||||
TRANSLATIONS_FOR_TYPE(GL_SHORT),
|
||||
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
|
||||
TRANSLATIONS_FOR_TYPE(GL_FIXED),
|
||||
TRANSLATIONS_FOR_TYPE(GL_FLOAT)
|
||||
};
|
||||
|
||||
void VertexDataManager::checkVertexCaps(DWORD declTypes)
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < 2; j++)
|
||||
{
|
||||
for (unsigned int k = 0; k < 4; k++)
|
||||
{
|
||||
if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
|
||||
{
|
||||
mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is used to index mAttributeTypes and mPossibleTranslations.
|
||||
unsigned int VertexDataManager::typeIndex(GLenum type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_BYTE: return 0;
|
||||
case GL_UNSIGNED_BYTE: return 1;
|
||||
case GL_SHORT: return 2;
|
||||
case GL_UNSIGNED_SHORT: return 3;
|
||||
case GL_FIXED: return 4;
|
||||
case GL_FLOAT: return 5;
|
||||
|
||||
default: UNREACHABLE(); return 5;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes)
|
||||
{
|
||||
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS];
|
||||
D3DVERTEXELEMENT9 *element = &elements[0];
|
||||
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
if (attributes[i].active)
|
||||
{
|
||||
mDevice->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
|
||||
|
||||
element->Stream = i;
|
||||
element->Offset = 0;
|
||||
element->Type = attributes[i].type;
|
||||
element->Method = D3DDECLMETHOD_DEFAULT;
|
||||
element->Usage = D3DDECLUSAGE_TEXCOORD;
|
||||
element->UsageIndex = attributes[i].semanticIndex;
|
||||
element++;
|
||||
}
|
||||
}
|
||||
|
||||
static const D3DVERTEXELEMENT9 end = D3DDECL_END();
|
||||
*element = end;
|
||||
|
||||
IDirect3DVertexDeclaration9 *vertexDeclaration;
|
||||
mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
|
||||
mDevice->SetVertexDeclaration(vertexDeclaration);
|
||||
vertexDeclaration->Release();
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
D3DPOOL pool = getDisplay()->getBufferPool(usageFlags);
|
||||
HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
mVertexBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void VertexBuffer::unmap()
|
||||
{
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
mVertexBuffer->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
IDirect3DVertexBuffer9 *VertexBuffer::getBuffer() const
|
||||
{
|
||||
return mVertexBuffer;
|
||||
}
|
||||
|
||||
ConstantVertexBuffer::ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w) : VertexBuffer(device, 4 * sizeof(float), D3DUSAGE_WRITEONLY)
|
||||
{
|
||||
void *buffer = NULL;
|
||||
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
HRESULT result = mVertexBuffer->Lock(0, 0, &buffer, 0);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Lock failed with error 0x%08x", result);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
float *vector = (float*)buffer;
|
||||
|
||||
vector[0] = x;
|
||||
vector[1] = y;
|
||||
vector[2] = z;
|
||||
vector[3] = w;
|
||||
|
||||
mVertexBuffer->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
ConstantVertexBuffer::~ConstantVertexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
ArrayVertexBuffer::ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : VertexBuffer(device, size, usageFlags)
|
||||
{
|
||||
mBufferSize = size;
|
||||
mWritePosition = 0;
|
||||
mRequiredSpace = 0;
|
||||
}
|
||||
|
||||
ArrayVertexBuffer::~ArrayVertexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace)
|
||||
{
|
||||
mRequiredSpace += requiredSpace;
|
||||
}
|
||||
|
||||
void ArrayVertexBuffer::addRequiredSpaceFor(ArrayVertexBuffer *buffer)
|
||||
{
|
||||
mRequiredSpace += buffer->mRequiredSpace;
|
||||
}
|
||||
|
||||
StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
|
||||
{
|
||||
}
|
||||
|
||||
StreamingVertexBuffer::~StreamingVertexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void *StreamingVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *offset)
|
||||
{
|
||||
void *mapPtr = NULL;
|
||||
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Lock failed with error 0x%08x", result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*offset = mWritePosition;
|
||||
mWritePosition += requiredSpace;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
void StreamingVertexBuffer::reserveRequiredSpace()
|
||||
{
|
||||
if (mRequiredSpace > mBufferSize)
|
||||
{
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
mVertexBuffer->Release();
|
||||
mVertexBuffer = NULL;
|
||||
}
|
||||
|
||||
mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2); // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
|
||||
|
||||
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
|
||||
HRESULT result = mDevice->CreateVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
|
||||
}
|
||||
|
||||
mWritePosition = 0;
|
||||
}
|
||||
else if (mWritePosition + mRequiredSpace > mBufferSize) // Recycle
|
||||
{
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
void *dummy;
|
||||
mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
|
||||
mVertexBuffer->Unlock();
|
||||
}
|
||||
|
||||
mWritePosition = 0;
|
||||
}
|
||||
|
||||
mRequiredSpace = 0;
|
||||
}
|
||||
|
||||
StaticVertexBuffer::StaticVertexBuffer(IDirect3DDevice9 *device) : ArrayVertexBuffer(device, 0, D3DUSAGE_WRITEONLY)
|
||||
{
|
||||
}
|
||||
|
||||
StaticVertexBuffer::~StaticVertexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, UINT *streamOffset)
|
||||
{
|
||||
void *mapPtr = NULL;
|
||||
|
||||
if (mVertexBuffer)
|
||||
{
|
||||
HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Lock failed with error 0x%08x", result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int attributeOffset = attribute.mOffset % attribute.stride();
|
||||
VertexElement element = {attribute.mType, attribute.mSize, attribute.mNormalized, attributeOffset, mWritePosition};
|
||||
mCache.push_back(element);
|
||||
|
||||
*streamOffset = mWritePosition;
|
||||
mWritePosition += requiredSpace;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
void StaticVertexBuffer::reserveRequiredSpace()
|
||||
{
|
||||
if (!mVertexBuffer && mBufferSize == 0)
|
||||
{
|
||||
D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
|
||||
HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
|
||||
}
|
||||
|
||||
mBufferSize = mRequiredSpace;
|
||||
}
|
||||
else if (mVertexBuffer && mBufferSize >= mRequiredSpace)
|
||||
{
|
||||
// Already allocated
|
||||
}
|
||||
else UNREACHABLE(); // Static vertex buffers can't be resized
|
||||
|
||||
mRequiredSpace = 0;
|
||||
}
|
||||
|
||||
UINT StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute)
|
||||
{
|
||||
for (unsigned int element = 0; element < mCache.size(); element++)
|
||||
{
|
||||
if (mCache[element].type == attribute.mType && mCache[element].size == attribute.mSize && mCache[element].normalized == attribute.mNormalized)
|
||||
{
|
||||
if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
|
||||
{
|
||||
return mCache[element].streamOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const VertexDataManager::FormatConverter &VertexDataManager::formatConverter(const VertexAttribute &attribute) const
|
||||
{
|
||||
return mAttributeTypes[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/VertexDataManager.h: Defines the VertexDataManager, a class that
|
||||
// runs the Buffer translation process.
|
||||
|
||||
#ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
|
||||
#define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "libGLESv2/Context.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
struct TranslatedAttribute
|
||||
{
|
||||
bool active;
|
||||
|
||||
D3DDECLTYPE type;
|
||||
UINT offset;
|
||||
UINT stride; // 0 means not to advance the read pointer at all
|
||||
UINT semanticIndex;
|
||||
|
||||
IDirect3DVertexBuffer9 *vertexBuffer;
|
||||
};
|
||||
|
||||
class VertexBuffer
|
||||
{
|
||||
public:
|
||||
VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
void unmap();
|
||||
|
||||
IDirect3DVertexBuffer9 *getBuffer() const;
|
||||
|
||||
protected:
|
||||
IDirect3DDevice9 *const mDevice;
|
||||
IDirect3DVertexBuffer9 *mVertexBuffer;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
|
||||
};
|
||||
|
||||
class ConstantVertexBuffer : public VertexBuffer
|
||||
{
|
||||
public:
|
||||
ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
|
||||
~ConstantVertexBuffer();
|
||||
};
|
||||
|
||||
class ArrayVertexBuffer : public VertexBuffer
|
||||
{
|
||||
public:
|
||||
ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
|
||||
~ArrayVertexBuffer();
|
||||
|
||||
UINT size() const { return mBufferSize; }
|
||||
virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
|
||||
virtual void reserveRequiredSpace() = 0;
|
||||
void addRequiredSpace(UINT requiredSpace);
|
||||
void addRequiredSpaceFor(ArrayVertexBuffer *buffer);
|
||||
|
||||
protected:
|
||||
UINT mBufferSize;
|
||||
UINT mWritePosition;
|
||||
UINT mRequiredSpace;
|
||||
};
|
||||
|
||||
class StreamingVertexBuffer : public ArrayVertexBuffer
|
||||
{
|
||||
public:
|
||||
StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
|
||||
~StreamingVertexBuffer();
|
||||
|
||||
void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
|
||||
void reserveRequiredSpace();
|
||||
};
|
||||
|
||||
class StaticVertexBuffer : public ArrayVertexBuffer
|
||||
{
|
||||
public:
|
||||
explicit StaticVertexBuffer(IDirect3DDevice9 *device);
|
||||
~StaticVertexBuffer();
|
||||
|
||||
void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
|
||||
void reserveRequiredSpace();
|
||||
|
||||
UINT lookupAttribute(const VertexAttribute &attribute); // Returns the offset into the vertex buffer, or -1 if not found
|
||||
|
||||
private:
|
||||
struct VertexElement
|
||||
{
|
||||
GLenum type;
|
||||
GLint size;
|
||||
bool normalized;
|
||||
int attributeOffset;
|
||||
|
||||
UINT streamOffset;
|
||||
};
|
||||
|
||||
std::vector<VertexElement> mCache;
|
||||
};
|
||||
|
||||
class VertexDataManager
|
||||
{
|
||||
public:
|
||||
VertexDataManager(Context *context, IDirect3DDevice9 *backend);
|
||||
virtual ~VertexDataManager();
|
||||
|
||||
void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
|
||||
|
||||
void setupAttributes(const TranslatedAttribute *attributes);
|
||||
GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
|
||||
|
||||
UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
|
||||
UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
|
||||
|
||||
Context *const mContext;
|
||||
IDirect3DDevice9 *const mDevice;
|
||||
|
||||
StreamingVertexBuffer *mStreamingBuffer;
|
||||
|
||||
bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
|
||||
ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
|
||||
|
||||
// Attribute format conversion
|
||||
struct FormatConverter
|
||||
{
|
||||
bool identity;
|
||||
std::size_t outputElementSize;
|
||||
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
|
||||
D3DDECLTYPE d3dDeclType;
|
||||
};
|
||||
|
||||
enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
|
||||
|
||||
FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
|
||||
|
||||
struct TranslationDescription
|
||||
{
|
||||
DWORD capsFlag;
|
||||
FormatConverter preferredConversion;
|
||||
FormatConverter fallbackConversion;
|
||||
};
|
||||
|
||||
// This table is used to generate mAttributeTypes.
|
||||
static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
|
||||
|
||||
void checkVertexCaps(DWORD declTypes);
|
||||
|
||||
unsigned int typeIndex(GLenum type) const;
|
||||
const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
|
||||
// that must be implemented by any API-specific implementation of ANGLE.
|
||||
|
||||
#include "libGLESv2/geometry/backend.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
void *TranslatedBuffer::map(std::size_t requiredSpace, std::size_t *offset)
|
||||
{
|
||||
ASSERT(requiredSpace <= mBufferSize);
|
||||
|
||||
reserveSpace(requiredSpace);
|
||||
|
||||
*offset = mCurrentPoint;
|
||||
mCurrentPoint += requiredSpace;
|
||||
|
||||
return streamingMap(*offset, requiredSpace);
|
||||
}
|
||||
|
||||
void TranslatedBuffer::reserveSpace(std::size_t requiredSpace)
|
||||
{
|
||||
if (mCurrentPoint + requiredSpace > mBufferSize)
|
||||
{
|
||||
recycle();
|
||||
mCurrentPoint = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
|
||||
// that must be implemented by any API-specific implementation of ANGLE.
|
||||
|
||||
#ifndef LIBGLESV2_GEOMETRY_BACKEND_H_
|
||||
#define LIBGLESV2_GEOMETRY_BACKEND_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "libGLESv2/Context.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class TranslatedVertexBuffer;
|
||||
class TranslatedIndexBuffer;
|
||||
|
||||
struct FormatConverter
|
||||
{
|
||||
bool identity;
|
||||
std::size_t outputVertexSize;
|
||||
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
|
||||
};
|
||||
|
||||
struct TranslatedAttribute
|
||||
{
|
||||
bool enabled;
|
||||
bool nonArray;
|
||||
|
||||
// These are the original untranslated values. (Or just have some sort of BufferBackEnd::TranslatedTypeKey.)
|
||||
GLenum type;
|
||||
std::size_t size;
|
||||
bool normalized;
|
||||
|
||||
std::size_t offset;
|
||||
|
||||
std::size_t stride; // 0 means not to advance the read pointer at all
|
||||
|
||||
std::size_t semanticIndex;
|
||||
|
||||
TranslatedVertexBuffer *buffer;
|
||||
};
|
||||
|
||||
class BufferBackEnd
|
||||
{
|
||||
public:
|
||||
virtual ~BufferBackEnd() { }
|
||||
|
||||
virtual bool supportIntIndices() = 0;
|
||||
|
||||
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0;
|
||||
virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size) = 0;
|
||||
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type) = 0;
|
||||
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
|
||||
|
||||
// For an identity-mappable stream, verify that the stride and offset are okay.
|
||||
virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const = 0;
|
||||
|
||||
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
|
||||
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
|
||||
|
||||
virtual void invalidate() = 0;
|
||||
};
|
||||
|
||||
class TranslatedBuffer
|
||||
{
|
||||
public:
|
||||
explicit TranslatedBuffer(std::size_t size) : mBufferSize(size), mCurrentPoint(0) { }
|
||||
virtual ~TranslatedBuffer() { }
|
||||
|
||||
std::size_t size() const { return mBufferSize; }
|
||||
|
||||
virtual void *map() = 0;
|
||||
virtual void unmap() = 0;
|
||||
|
||||
void reserveSpace(std::size_t requiredSpace);
|
||||
|
||||
void *map(std::size_t requiredSpace, std::size_t *offset);
|
||||
|
||||
protected:
|
||||
virtual void recycle() = 0;
|
||||
virtual void *streamingMap(std::size_t offset, std::size_t size) = 0;
|
||||
|
||||
private:
|
||||
std::size_t mBufferSize;
|
||||
std::size_t mCurrentPoint;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TranslatedBuffer);
|
||||
};
|
||||
|
||||
class TranslatedVertexBuffer : public TranslatedBuffer
|
||||
{
|
||||
public:
|
||||
explicit TranslatedVertexBuffer(std::size_t size) : TranslatedBuffer(size) { }
|
||||
};
|
||||
|
||||
class TranslatedIndexBuffer : public TranslatedBuffer
|
||||
{
|
||||
public:
|
||||
explicit TranslatedIndexBuffer(std::size_t size) : TranslatedBuffer(size) { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_GEOMETRY_BACKEND_H_
|
|
@ -1,646 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
|
||||
|
||||
#include "libGLESv2/geometry/dx9.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#define GL_APICALL
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include "libGLESv2/Context.h"
|
||||
#include "libGLESv2/main.h"
|
||||
#include "libGLESv2/geometry/vertexconversion.h"
|
||||
#include "libGLESv2/geometry/IndexDataManager.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
|
||||
//
|
||||
// BYTE SHORT (Cast)
|
||||
// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
|
||||
// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast)
|
||||
// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize)
|
||||
// SHORT SHORT (Identity)
|
||||
// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize)
|
||||
// UNSIGNED_SHORT FLOAT (Cast)
|
||||
// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize)
|
||||
// FIXED (not in WebGL) FLOAT (FixedToFloat)
|
||||
// FLOAT FLOAT (Identity)
|
||||
|
||||
// GLToCType maps from GL type (as GLenum) to the C typedef.
|
||||
template <GLenum GLType> struct GLToCType { };
|
||||
|
||||
template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
|
||||
template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
|
||||
template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
|
||||
template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
|
||||
template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
|
||||
template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
|
||||
|
||||
// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
|
||||
enum D3DVertexType
|
||||
{
|
||||
D3DVT_FLOAT,
|
||||
D3DVT_SHORT,
|
||||
D3DVT_SHORT_NORM,
|
||||
D3DVT_UBYTE,
|
||||
D3DVT_UBYTE_NORM,
|
||||
D3DVT_USHORT_NORM
|
||||
};
|
||||
|
||||
// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
|
||||
template <unsigned int D3DType> struct D3DToCType { };
|
||||
|
||||
template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
|
||||
template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
|
||||
template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
|
||||
template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
|
||||
template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
|
||||
template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
|
||||
|
||||
// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
|
||||
template <unsigned int type, int size>
|
||||
struct WidenRule
|
||||
{
|
||||
};
|
||||
|
||||
template <int size> struct WidenRule<D3DVT_FLOAT, size> : gl::NoWiden<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_SHORT, size> : gl::WidenToEven<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : gl::WidenToEven<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_UBYTE, size> : gl::WidenToFour<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : gl::WidenToFour<size> { };
|
||||
template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : gl::WidenToEven<size> { };
|
||||
|
||||
// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
|
||||
template <unsigned int d3dtype, int size>
|
||||
struct VertexTypeFlags
|
||||
{
|
||||
};
|
||||
|
||||
template <unsigned int capflag, unsigned int declflag>
|
||||
struct VertexTypeFlagsHelper
|
||||
{
|
||||
enum { capflag = capflag };
|
||||
enum { declflag = declflag };
|
||||
};
|
||||
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
|
||||
template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
|
||||
|
||||
|
||||
// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
|
||||
template <GLenum GLtype, bool normalized>
|
||||
struct VertexTypeMapping
|
||||
{
|
||||
};
|
||||
|
||||
template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
|
||||
struct VertexTypeMappingBase
|
||||
{
|
||||
enum { preferred = Preferred };
|
||||
enum { fallback = Fallback };
|
||||
};
|
||||
|
||||
template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast
|
||||
template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize
|
||||
template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity
|
||||
template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast
|
||||
template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
|
||||
template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat
|
||||
template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity
|
||||
|
||||
|
||||
// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
|
||||
// The conversion rules themselves are defined in vertexconversion.h.
|
||||
|
||||
// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
|
||||
template <GLenum fromType, bool normalized, unsigned int toType>
|
||||
struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
|
||||
{
|
||||
};
|
||||
|
||||
// All conversions from normalized types to float use the Normalize operator.
|
||||
template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { };
|
||||
|
||||
// Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules.
|
||||
template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
|
||||
template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 16> { };
|
||||
|
||||
// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
|
||||
// whether it is normalized or not.
|
||||
template <class T, bool normalized>
|
||||
struct DefaultVertexValuesStage2
|
||||
{
|
||||
};
|
||||
|
||||
template <class T> struct DefaultVertexValuesStage2<T, true> : gl::NormalizedDefaultValues<T> { };
|
||||
template <class T> struct DefaultVertexValuesStage2<T, false> : gl::SimpleDefaultValues<T> { };
|
||||
|
||||
// Work out the default value rule for a D3D type (expressed as the C type) and
|
||||
template <class T, bool normalized>
|
||||
struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
|
||||
{
|
||||
};
|
||||
|
||||
template <bool normalized> struct DefaultVertexValues<float, normalized> : gl::SimpleDefaultValues<float> { };
|
||||
|
||||
// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
|
||||
// The fallback conversion produces an output that all D3D9 devices must support.
|
||||
template <class T> struct UsePreferred { enum { type = T::preferred }; };
|
||||
template <class T> struct UseFallback { enum { type = T::fallback }; };
|
||||
|
||||
// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
|
||||
// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
|
||||
// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
|
||||
template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
|
||||
struct Converter
|
||||
: gl::VertexDataConverter<typename GLToCType<fromType>::type,
|
||||
WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
|
||||
ConversionRule<fromType,
|
||||
normalized,
|
||||
PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
|
||||
DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
|
||||
{
|
||||
private:
|
||||
enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
|
||||
enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
|
||||
|
||||
public:
|
||||
enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
|
||||
enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace gl
|
||||
{
|
||||
Dx9BackEnd::Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice)
|
||||
: mDevice(d3ddevice)
|
||||
{
|
||||
mDevice->AddRef();
|
||||
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
|
||||
{
|
||||
mAppliedAttribEnabled[i] = true;
|
||||
mStreamFrequency[i] = STREAM_FREQUENCY_UNINSTANCED;
|
||||
}
|
||||
|
||||
mStreamFrequency[MAX_VERTEX_ATTRIBS] = STREAM_FREQUENCY_UNINSTANCED;
|
||||
|
||||
D3DCAPS9 caps = context->getDeviceCaps();
|
||||
|
||||
IDirect3D9 *d3dObject;
|
||||
mDevice->GetDirect3D(&d3dObject);
|
||||
|
||||
D3DADAPTER_IDENTIFIER9 ident;
|
||||
d3dObject->GetAdapterIdentifier(caps.AdapterOrdinal, 0, &ident);
|
||||
d3dObject->Release();
|
||||
|
||||
// Instancing is mandatory for all HW with SM3 vertex shaders, but avoid hardware where it does not work.
|
||||
mUseInstancingForStrideZero = (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) && ident.VendorId != 0x8086);
|
||||
mSupportIntIndices = (caps.MaxVertexIndex >= (1 << 16));
|
||||
|
||||
checkVertexCaps(caps.DeclTypes);
|
||||
}
|
||||
|
||||
Dx9BackEnd::~Dx9BackEnd()
|
||||
{
|
||||
mDevice->Release();
|
||||
}
|
||||
|
||||
bool Dx9BackEnd::supportIntIndices()
|
||||
{
|
||||
return mSupportIntIndices;
|
||||
}
|
||||
|
||||
// Initialise a TranslationInfo
|
||||
#define TRANSLATION(type, norm, size, preferred) \
|
||||
{ \
|
||||
{ \
|
||||
Converter<type, norm, size, preferred>::identity, \
|
||||
Converter<type, norm, size, preferred>::finalSize, \
|
||||
Converter<type, norm, size, preferred>::convertArray, \
|
||||
}, \
|
||||
static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
|
||||
}
|
||||
|
||||
#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
|
||||
{ \
|
||||
Converter<type, norm, size, UsePreferred>::capflag, \
|
||||
TRANSLATION(type, norm, size, UsePreferred), \
|
||||
TRANSLATION(type, norm, size, UseFallback) \
|
||||
}
|
||||
|
||||
#define TRANSLATIONS_FOR_TYPE(type) \
|
||||
{ \
|
||||
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
|
||||
{ TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \
|
||||
}
|
||||
|
||||
const Dx9BackEnd::TranslationDescription Dx9BackEnd::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
|
||||
{
|
||||
TRANSLATIONS_FOR_TYPE(GL_BYTE),
|
||||
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
|
||||
TRANSLATIONS_FOR_TYPE(GL_SHORT),
|
||||
TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
|
||||
TRANSLATIONS_FOR_TYPE(GL_FIXED),
|
||||
TRANSLATIONS_FOR_TYPE(GL_FLOAT)
|
||||
};
|
||||
|
||||
void Dx9BackEnd::checkVertexCaps(DWORD declTypes)
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < 2; j++)
|
||||
{
|
||||
for (unsigned int k = 0; k < 4; k++)
|
||||
{
|
||||
if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
|
||||
{
|
||||
mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
|
||||
}
|
||||
else
|
||||
{
|
||||
mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TranslatedVertexBuffer *Dx9BackEnd::createVertexBuffer(std::size_t size)
|
||||
{
|
||||
return new Dx9VertexBuffer(mDevice, size);
|
||||
}
|
||||
|
||||
TranslatedVertexBuffer *Dx9BackEnd::createVertexBufferForStrideZero(std::size_t size)
|
||||
{
|
||||
if (mUseInstancingForStrideZero)
|
||||
{
|
||||
return new Dx9VertexBuffer(mDevice, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Dx9VertexBufferZeroStrideWorkaround(mDevice, size);
|
||||
}
|
||||
}
|
||||
|
||||
TranslatedIndexBuffer *Dx9BackEnd::createIndexBuffer(std::size_t size, GLenum type)
|
||||
{
|
||||
return new Dx9IndexBuffer(mDevice, size, type);
|
||||
}
|
||||
|
||||
// This is used to index mAttributeTypes and mPossibleTranslations.
|
||||
unsigned int Dx9BackEnd::typeIndex(GLenum type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_BYTE: return 0;
|
||||
case GL_UNSIGNED_BYTE: return 1;
|
||||
case GL_SHORT: return 2;
|
||||
case GL_UNSIGNED_SHORT: return 3;
|
||||
case GL_FIXED: return 4;
|
||||
case GL_FLOAT: return 5;
|
||||
|
||||
default: UNREACHABLE(); return 5;
|
||||
}
|
||||
}
|
||||
|
||||
FormatConverter Dx9BackEnd::getFormatConverter(GLenum type, std::size_t size, bool normalize)
|
||||
{
|
||||
return mAttributeTypes[typeIndex(type)][normalize][size-1].formatConverter;
|
||||
}
|
||||
|
||||
D3DDECLTYPE Dx9BackEnd::mapAttributeType(GLenum type, std::size_t size, bool normalize) const
|
||||
{
|
||||
return mAttributeTypes[typeIndex(type)][normalize][size-1].d3dDeclType;
|
||||
}
|
||||
|
||||
bool Dx9BackEnd::validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const
|
||||
{
|
||||
// D3D9 requires the stream offset and stride to be a multiple of DWORD.
|
||||
return (stride % sizeof(DWORD) == 0 && offset % sizeof(DWORD) == 0);
|
||||
}
|
||||
|
||||
IDirect3DVertexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedVertexBuffer *vb) const
|
||||
{
|
||||
return vb ? static_cast<Dx9VertexBuffer*>(vb)->getBuffer() : NULL;
|
||||
}
|
||||
|
||||
IDirect3DIndexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedIndexBuffer *ib) const
|
||||
{
|
||||
return ib ? static_cast<Dx9IndexBuffer*>(ib)->getBuffer() : NULL;
|
||||
}
|
||||
|
||||
GLenum Dx9BackEnd::setupIndicesPreDraw(const TranslatedIndexData &indexInfo)
|
||||
{
|
||||
mDevice->SetIndices(getDxBuffer(indexInfo.buffer));
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum Dx9BackEnd::setupAttributesPreDraw(const TranslatedAttribute *attributes)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS+1];
|
||||
|
||||
D3DVERTEXELEMENT9 *nextElement = &elements[0];
|
||||
|
||||
for (BYTE i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
if (attributes[i].enabled)
|
||||
{
|
||||
nextElement->Stream = i + 1; // Stream 0 is skipped because D3D does not permit it to be an instanced stream.
|
||||
nextElement->Offset = 0;
|
||||
nextElement->Type = static_cast<BYTE>(mapAttributeType(attributes[i].type, attributes[i].size, attributes[i].normalized));
|
||||
nextElement->Method = D3DDECLMETHOD_DEFAULT;
|
||||
nextElement->Usage = D3DDECLUSAGE_TEXCOORD;
|
||||
nextElement->UsageIndex = attributes[i].semanticIndex;
|
||||
nextElement++;
|
||||
}
|
||||
}
|
||||
|
||||
static const D3DVERTEXELEMENT9 end = D3DDECL_END();
|
||||
*nextElement = end;
|
||||
|
||||
IDirect3DVertexDeclaration9* vertexDeclaration;
|
||||
hr = mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
|
||||
mDevice->SetVertexDeclaration(vertexDeclaration);
|
||||
vertexDeclaration->Release();
|
||||
|
||||
mDevice->SetStreamSource(0, NULL, 0, 0);
|
||||
|
||||
bool nonArrayAttributes = false;
|
||||
|
||||
for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
if (attributes[i].enabled)
|
||||
{
|
||||
if (attributes[i].nonArray) nonArrayAttributes = true;
|
||||
|
||||
mDevice->SetStreamSource(i + 1, getDxBuffer(attributes[i].buffer), attributes[i].offset, attributes[i].stride);
|
||||
if (!mAppliedAttribEnabled[i])
|
||||
{
|
||||
mAppliedAttribEnabled[i] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mAppliedAttribEnabled[i])
|
||||
{
|
||||
mDevice->SetStreamSource(i + 1, 0, 0, 0);
|
||||
mAppliedAttribEnabled[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mUseInstancingForStrideZero)
|
||||
{
|
||||
// When there are no stride zero attributes, we disable instancing so that DrawPrimitive can be used.
|
||||
|
||||
if (nonArrayAttributes)
|
||||
{
|
||||
if (mStreamFrequency[0] != STREAM_FREQUENCY_INDEXED)
|
||||
{
|
||||
mStreamFrequency[0] = STREAM_FREQUENCY_INDEXED;
|
||||
mDevice->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | 1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
|
||||
{
|
||||
if (attributes[i].enabled)
|
||||
{
|
||||
if (attributes[i].nonArray)
|
||||
{
|
||||
if (mStreamFrequency[i+1] != STREAM_FREQUENCY_INSTANCED)
|
||||
{
|
||||
mStreamFrequency[i+1] = STREAM_FREQUENCY_INSTANCED;
|
||||
mDevice->SetStreamSourceFreq(i + 1, D3DSTREAMSOURCE_INSTANCEDATA | 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mStreamFrequency[i+1] != STREAM_FREQUENCY_INDEXED)
|
||||
{
|
||||
mStreamFrequency[i+1] = STREAM_FREQUENCY_INDEXED;
|
||||
mDevice->SetStreamSourceFreq(i + 1, D3DSTREAMSOURCE_INDEXEDDATA | 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < MAX_VERTEX_ATTRIBS + 1; i++)
|
||||
{
|
||||
if (mStreamFrequency[i] != STREAM_FREQUENCY_UNINSTANCED)
|
||||
{
|
||||
mStreamFrequency[i] = STREAM_FREQUENCY_UNINSTANCED;
|
||||
|
||||
// This should not be needed, but otherwise there is a buggy driver that will leave instancing
|
||||
// enabled for the first draw after it has been turned off.
|
||||
mDevice->SetStreamSourceFreq(i, D3DSTREAMSOURCE_INDEXEDDATA | 1);
|
||||
|
||||
mDevice->SetStreamSourceFreq(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
void Dx9BackEnd::invalidate()
|
||||
{
|
||||
for (int i = 0; i < MAX_VERTEX_ATTRIBS + 1; i++)
|
||||
{
|
||||
mStreamFrequency[i] = STREAM_FREQUENCY_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size)
|
||||
: TranslatedVertexBuffer(size)
|
||||
{
|
||||
HRESULT hr = device->CreateVertexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", size);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags)
|
||||
: TranslatedVertexBuffer(size)
|
||||
{
|
||||
HRESULT hr = device->CreateVertexBuffer(size, usageFlags, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
ERR("Out of memory allocating a vertex buffer of size %lu.", size);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Dx9BackEnd::Dx9VertexBuffer::~Dx9VertexBuffer()
|
||||
{
|
||||
mVertexBuffer->Release();
|
||||
}
|
||||
|
||||
IDirect3DVertexBuffer9 *Dx9BackEnd::Dx9VertexBuffer::getBuffer() const
|
||||
{
|
||||
return mVertexBuffer;
|
||||
}
|
||||
|
||||
void *Dx9BackEnd::Dx9VertexBuffer::map()
|
||||
{
|
||||
void *mapPtr;
|
||||
|
||||
HRESULT hr = mVertexBuffer->Lock(0, 0, &mapPtr, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
void Dx9BackEnd::Dx9VertexBuffer::unmap()
|
||||
{
|
||||
mVertexBuffer->Unlock();
|
||||
}
|
||||
|
||||
void Dx9BackEnd::Dx9VertexBuffer::recycle()
|
||||
{
|
||||
void *dummy;
|
||||
mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
|
||||
mVertexBuffer->Unlock();
|
||||
}
|
||||
|
||||
void *Dx9BackEnd::Dx9VertexBuffer::streamingMap(std::size_t offset, std::size_t size)
|
||||
{
|
||||
void *mapPtr;
|
||||
|
||||
HRESULT hr = mVertexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
// Normally VBs are created with D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, but some hardware & drivers won't render
|
||||
// if any stride-zero streams are in D3DUSAGE_DYNAMIC VBs, so this provides a way to create such VBs with only D3DUSAGE_WRITEONLY set.
|
||||
// D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE are only available on D3DUSAGE_DYNAMIC VBs, so we override methods to avoid using these flags.
|
||||
Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size)
|
||||
: Dx9VertexBuffer(device, size, D3DUSAGE_WRITEONLY)
|
||||
{
|
||||
}
|
||||
|
||||
void Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::recycle()
|
||||
{
|
||||
}
|
||||
|
||||
void *Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::streamingMap(std::size_t offset, std::size_t size)
|
||||
{
|
||||
void *mapPtr;
|
||||
|
||||
HRESULT hr = getBuffer()->Lock(offset, size, &mapPtr, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
Dx9BackEnd::Dx9IndexBuffer::Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type)
|
||||
: TranslatedIndexBuffer(size)
|
||||
{
|
||||
ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT);
|
||||
|
||||
D3DFORMAT format = (type == GL_UNSIGNED_SHORT) ? D3DFMT_INDEX16 : D3DFMT_INDEX32;
|
||||
|
||||
HRESULT hr = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, D3DPOOL_DEFAULT, &mIndexBuffer, NULL);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
ERR("Out of memory allocating an index buffer of size %lu.", size);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
Dx9BackEnd::Dx9IndexBuffer::~Dx9IndexBuffer()
|
||||
{
|
||||
mIndexBuffer->Release();
|
||||
}
|
||||
|
||||
IDirect3DIndexBuffer9*Dx9BackEnd::Dx9IndexBuffer::getBuffer() const
|
||||
{
|
||||
return mIndexBuffer;
|
||||
}
|
||||
|
||||
void *Dx9BackEnd::Dx9IndexBuffer::map()
|
||||
{
|
||||
void *mapPtr;
|
||||
|
||||
HRESULT hr = mIndexBuffer->Lock(0, 0, &mapPtr, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
void Dx9BackEnd::Dx9IndexBuffer::unmap()
|
||||
{
|
||||
mIndexBuffer->Unlock();
|
||||
}
|
||||
|
||||
void Dx9BackEnd::Dx9IndexBuffer::recycle()
|
||||
{
|
||||
void *dummy;
|
||||
mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
|
||||
mIndexBuffer->Unlock();
|
||||
}
|
||||
|
||||
void *Dx9BackEnd::Dx9IndexBuffer::streamingMap(std::size_t offset, std::size_t size)
|
||||
{
|
||||
void *mapPtr;
|
||||
|
||||
HRESULT hr = mIndexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR(" Lock failed with error 0x%08x", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mapPtr;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
|
||||
|
||||
#ifndef LIBGLESV2_GEOMETRY_DX9_H_
|
||||
#define LIBGLESV2_GEOMETRY_DX9_H_
|
||||
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "libGLESv2/Buffer.h"
|
||||
#include "libGLESv2/geometry/backend.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
class Dx9BackEnd : public BufferBackEnd
|
||||
{
|
||||
public:
|
||||
explicit Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice);
|
||||
~Dx9BackEnd();
|
||||
|
||||
virtual bool supportIntIndices();
|
||||
|
||||
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size);
|
||||
virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size);
|
||||
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type);
|
||||
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
|
||||
|
||||
virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
|
||||
|
||||
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
|
||||
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);
|
||||
|
||||
void invalidate();
|
||||
|
||||
private:
|
||||
IDirect3DDevice9 *mDevice;
|
||||
|
||||
bool mUseInstancingForStrideZero;
|
||||
bool mSupportIntIndices;
|
||||
|
||||
bool mAppliedAttribEnabled[MAX_VERTEX_ATTRIBS];
|
||||
|
||||
enum StreamFrequency
|
||||
{
|
||||
STREAM_FREQUENCY_UNINSTANCED = 0,
|
||||
STREAM_FREQUENCY_INDEXED,
|
||||
STREAM_FREQUENCY_INSTANCED,
|
||||
STREAM_FREQUENCY_DIRTY
|
||||
};
|
||||
|
||||
StreamFrequency mStreamFrequency[MAX_VERTEX_ATTRIBS+1]; // Stream frequencies as last set.
|
||||
|
||||
struct TranslationInfo
|
||||
{
|
||||
FormatConverter formatConverter;
|
||||
D3DDECLTYPE d3dDeclType;
|
||||
};
|
||||
|
||||
enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
|
||||
|
||||
TranslationInfo mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
|
||||
|
||||
struct TranslationDescription
|
||||
{
|
||||
DWORD capsFlag;
|
||||
TranslationInfo preferredConversion;
|
||||
TranslationInfo fallbackConversion;
|
||||
};
|
||||
|
||||
// This table is used to generate mAttributeTypes.
|
||||
static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
|
||||
|
||||
void checkVertexCaps(DWORD declTypes);
|
||||
|
||||
unsigned int typeIndex(GLenum type) const;
|
||||
|
||||
class Dx9VertexBuffer : public TranslatedVertexBuffer
|
||||
{
|
||||
public:
|
||||
Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size);
|
||||
virtual ~Dx9VertexBuffer();
|
||||
|
||||
IDirect3DVertexBuffer9 *getBuffer() const;
|
||||
|
||||
protected:
|
||||
Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
|
||||
|
||||
virtual void *map();
|
||||
virtual void unmap();
|
||||
|
||||
virtual void recycle();
|
||||
virtual void *streamingMap(std::size_t offset, std::size_t size);
|
||||
|
||||
private:
|
||||
IDirect3DVertexBuffer9 *mVertexBuffer;
|
||||
};
|
||||
|
||||
class Dx9VertexBufferZeroStrideWorkaround : public Dx9VertexBuffer
|
||||
{
|
||||
public:
|
||||
Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size);
|
||||
|
||||
protected:
|
||||
virtual void recycle();
|
||||
virtual void *streamingMap(std::size_t offset, std::size_t size);
|
||||
};
|
||||
|
||||
class Dx9IndexBuffer : public TranslatedIndexBuffer
|
||||
{
|
||||
public:
|
||||
Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type);
|
||||
virtual ~Dx9IndexBuffer();
|
||||
|
||||
IDirect3DIndexBuffer9 *getBuffer() const;
|
||||
|
||||
protected:
|
||||
virtual void *map();
|
||||
virtual void unmap();
|
||||
|
||||
virtual void recycle();
|
||||
virtual void *streamingMap(std::size_t offset, std::size_t size);
|
||||
|
||||
private:
|
||||
IDirect3DIndexBuffer9 *mIndexBuffer;
|
||||
};
|
||||
|
||||
IDirect3DVertexBuffer9 *getDxBuffer(TranslatedVertexBuffer *vb) const;
|
||||
IDirect3DIndexBuffer9 *getDxBuffer(TranslatedIndexBuffer *ib) const;
|
||||
|
||||
D3DDECLTYPE mapAttributeType(GLenum type, std::size_t size, bool normalized) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBGLESV2_GEOMETRY_DX9_H_
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче