Compare commits

...

3 commits

Author SHA1 Message Date
wuggy
6569a453d2 --enable-ctypes for clang-cl 2026-09-11 05:11:09 -07:00
wuggy
1d44f05fba clang on windows support 2026-09-10 08:32:59 -07:00
wuggy
b08f544172 Simplify class selector result collection 2026-09-09 12:00:04 -07:00
23 changed files with 212 additions and 77 deletions

View file

@ -11,3 +11,9 @@
GeckoSharedLibrary('lgpllibs', linkage=None)
SHARED_LIBRARY_NAME = 'lgpllibs'
if CONFIG['CLANG_CL']:
# SoundTouch uses clang's OpenMP runtime. Link its import library into the
# containing LGPL DLL and place the runtime beside the browser binaries.
OS_LIBS += ['C:/clang/lib/libomp']
FINAL_TARGET_FILES += ['C:/clang/bin/libomp.dll']

View file

@ -262,6 +262,13 @@ ifeq (WINNT,$(OS_TARGET))
NSS_XCFLAGS += $(filter -arch:%,$(CFLAGS))
endif
# freebl's x86 AES/GCM sources use AES-NI and PCLMUL intrinsics. The nested
# NSS build's per-object flags are not propagated through this wrapper when
# using clang-cl, so pass them explicitly.
ifeq (1,$(CLANG_CL))
NSS_XCFLAGS += -maes -mpclmul
endif
# Enable short header experiment. Firefox only.
NSS_XCFLAGS += -DNSS_ENABLE_TLS13_SHORT_HEADERS
@ -466,4 +473,3 @@ endif # MOZ_FOLD_LIBS
# Work around NSS build system race condition creating certdata.c in
# security/nss/lib/ckfw/builtins. See bug #836220.
libs-nss/lib$(if $(MOZ_FOLD_LIBS),/ckfw): $(call mkdir_deps,$(DEPTH)/security/nss/lib/ckfw/builtins)

View file

@ -27219,6 +27219,11 @@ static malloc_zone_t* _sqliteZone_;
#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE
# define SQLITE_USE_MALLOC_H 1
# define SQLITE_USE_MALLOC_USABLE_SIZE 1
# if defined(_WIN32)
/* Mozilla's jemalloc wrapper provides this symbol, but the Windows
* malloc.h does not declare it for clang-cl. */
extern size_t malloc_usable_size(void *);
# endif
/*
** The MSVCRT has malloc_usable_size(), but it is called _msize(). The
** use of _msize() is automatic, but can be disabled by compiling with

View file

@ -2927,12 +2927,11 @@ FindMatchingElementsWithId(const nsAString& aId, nsINode* aRoot,
// Actually find elements matching aSelectorList (which must not be
// null) and which are descendants of aRoot and put them in aList. If
// onlyFirstMatch, then stop once the first one is found.
template<bool onlyFirstMatch, class Collector, class T>
template<bool onlyFirstMatch, class T>
static void
FindMatchingElementsWithClass(nsINode* aRoot, nsIAtom* aClass,
nsCaseTreatment aCaseTreatment, T& aList)
{
Collector results;
for (nsIContent* cur = aRoot->GetFirstChild(); cur;
cur = cur->GetNextNode(aRoot)) {
if (!cur->IsElement()) {
@ -2944,14 +2943,7 @@ FindMatchingElementsWithClass(nsINode* aRoot, nsIAtom* aClass,
aList.AppendElement(cur->AsElement());
return;
}
results.AppendElement(cur->AsElement());
}
}
const uint32_t len = results.Length();
if (len) {
aList.SetCapacity(len);
for (uint32_t i = 0; i < len; ++i) {
aList.AppendElement(results.ElementAt(i));
aList.AppendElement(cur->AsElement());
}
}
}
@ -2975,7 +2967,7 @@ FindMatchingElements(nsINode* aRoot, nsCSSSelectorList* aSelectorList, T &aList,
nsCaseTreatment caseTreatment =
doc->GetCompatibilityMode() == eCompatibility_NavQuirks
? eIgnoreCase : eCaseMatters;
FindMatchingElementsWithClass<onlyFirstMatch, Collector>(
FindMatchingElementsWithClass<onlyFirstMatch>(
aRoot, selector->mClassList->mAtom, caseTreatment, aList);
return;
}

View file

@ -3694,12 +3694,12 @@ PluginInstanceChild::UpdateWindowAttributes(bool aForceSetWindow)
WINDOWPOS winpos = {
0, 0,
mWindow.x, mWindow.y,
mWindow.width, mWindow.height,
static_cast<int>(mWindow.width), static_cast<int>(mWindow.height),
0
};
NPEvent pluginEvent = {
WM_WINDOWPOSCHANGED, 0,
(LPARAM) &winpos
reinterpret_cast<uintptr_t>(&winpos)
};
mPluginIface->event(&mData, &pluginEvent);
}

View file

@ -1355,7 +1355,7 @@ public:
rv = httpChannel->GetReferrerPolicy(&referrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
switch (referrerPolicy) {
case nsIHttpChannel::REFERRER_POLICY_UNSET:
case static_cast<uint32_t>(nsIHttpChannel::REFERRER_POLICY_UNSET):
mReferrerPolicy = ReferrerPolicy::_empty;
break;
case nsIHttpChannel::REFERRER_POLICY_NO_REFERRER:

View file

@ -2774,7 +2774,7 @@ _cairo_d2d_copy_surface(cairo_d2d_surface_t *dst,
cairo_rectangle_int_t transformed_rect = { area_to_copy.x + translation->x,
area_to_copy.y + translation->y,
area_to_copy.width, area_to_copy.height };
cairo_rectangle_int_t surface_rect = { 0, 0, srcDesc.Width, srcDesc.Height };
cairo_rectangle_int_t surface_rect = { 0, 0, static_cast<int>(srcDesc.Width), static_cast<int>(srcDesc.Height) };
if (!_cairo_rectangle_contains(&surface_rect, &transformed_rect)) {
@ -2989,8 +2989,8 @@ _cairo_d2d_try_fastblit(cairo_d2d_surface_t *dst,
// Areas outside of the surface do not matter.
cairo_rectangle_int_t surface_rect = { 0, 0,
dst->rt->GetPixelSize().width,
dst->rt->GetPixelSize().height };
static_cast<int>(dst->rt->GetPixelSize().width),
static_cast<int>(dst->rt->GetPixelSize().height) };
cairo_region_intersect_rectangle(region, &surface_rect);
}

View file

@ -162,6 +162,13 @@ SOURCES += [
'xiph.c'
]
# dummy_funcs.c intentionally provides tentative definitions for FFmpeg
# objects that are disabled by the generated configuration. Clang's default
# -fno-common turns those placeholders into duplicate definitions when an
# enabled codec supplies the real object.
if CONFIG['CLANG_CL']:
SOURCES['dummy_funcs.c'].flags += ['-fcommon']
SYMBOLS_FILE = 'avcodec.symbols'
NO_VISIBILITY_FLAGS = True

View file

@ -41,7 +41,8 @@ static inline void atomic_int_set_win32(volatile int *ptr, int val)
#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_win32
static inline int atomic_int_add_and_fetch_win32(volatile int *ptr, int inc)
{
return inc + InterlockedExchangeAdd(ptr, inc);
/* Windows int and LONG are both 32-bit, but have distinct C types. */
return inc + InterlockedExchangeAdd((volatile LONG *)ptr, inc);
}
#define avpriv_atomic_ptr_cas atomic_ptr_cas_win32

View file

@ -85,10 +85,24 @@ COLD int dav1d_num_logical_processors(Dav1dContext *const c) {
#ifdef _WIN32
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
GROUP_AFFINITY affinity;
if (GetThreadGroupAffinity(GetCurrentThread(), &affinity)) {
int num_processors = 1;
while (affinity.Mask &= affinity.Mask - 1)
DWORD_PTR mask = 0, system_mask;
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
typedef BOOL (WINAPI *get_thread_group_affinity_fn)(HANDLE, PGROUP_AFFINITY);
get_thread_group_affinity_fn get_thread_group_affinity = kernel32 ?
(get_thread_group_affinity_fn)GetProcAddress(kernel32, "GetThreadGroupAffinity") : NULL;
/* Processor groups are only available on Windows 7 and later. */
if (get_thread_group_affinity &&
get_thread_group_affinity(GetCurrentThread(), &affinity))
mask = affinity.Mask;
else if (!GetProcessAffinityMask(GetCurrentProcess(), &mask, &system_mask))
mask = 0;
if (mask) {
int num_processors = 0;
do {
num_processors++;
} while (mask &= mask - 1);
return num_processors;
}
#else

View file

@ -33,8 +33,8 @@
#include <limits.h>
#include <windows.h>
#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
#define PTHREAD_MUTEX_INITIALIZER { 0 }
#define PTHREAD_ONCE_INIT 0
typedef struct {
HANDLE h;
@ -46,9 +46,16 @@ typedef struct {
unsigned stack_size;
} pthread_attr_t;
typedef SRWLOCK pthread_mutex_t;
typedef CONDITION_VARIABLE pthread_cond_t;
typedef INIT_ONCE pthread_once_t;
typedef struct {
volatile LONG state;
CRITICAL_SECTION cs;
} pthread_mutex_t;
struct dav1d_cond_waiter;
typedef struct {
CRITICAL_SECTION cs;
struct dav1d_cond_waiter *head;
} pthread_cond_t;
typedef volatile LONG pthread_once_t;
void dav1d_init_thread(void);
void dav1d_set_thread_name(const wchar_t *name);
@ -84,50 +91,51 @@ static inline int pthread_attr_setstacksize(pthread_attr_t *const attr,
static inline int pthread_mutex_init(pthread_mutex_t *const mutex,
const void *const attr)
{
InitializeSRWLock(mutex);
mutex->state = 0;
return 0;
}
static inline int pthread_mutex_destroy(pthread_mutex_t *const mutex) {
if (mutex->state == 2) DeleteCriticalSection(&mutex->cs);
return 0;
}
static inline int pthread_mutex_lock(pthread_mutex_t *const mutex) {
AcquireSRWLockExclusive(mutex);
if (InterlockedCompareExchange(&mutex->state, 1, 0) == 0) {
InitializeCriticalSection(&mutex->cs);
InterlockedExchange(&mutex->state, 2);
} else {
while (InterlockedCompareExchange(&mutex->state, 2, 2) != 2)
Sleep(1);
}
EnterCriticalSection(&mutex->cs);
return 0;
}
static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) {
ReleaseSRWLockExclusive(mutex);
LeaveCriticalSection(&mutex->cs);
return 0;
}
static inline int pthread_cond_init(pthread_cond_t *const cond,
const void *const attr)
{
InitializeConditionVariable(cond);
InitializeCriticalSection(&cond->cs);
cond->head = NULL;
return 0;
}
static inline int pthread_cond_destroy(pthread_cond_t *const cond) {
DeleteCriticalSection(&cond->cs);
return 0;
}
static inline int pthread_cond_wait(pthread_cond_t *const cond,
pthread_mutex_t *const mutex)
{
return !SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
}
static inline int pthread_cond_signal(pthread_cond_t *const cond) {
WakeConditionVariable(cond);
return 0;
}
static inline int pthread_cond_broadcast(pthread_cond_t *const cond) {
WakeAllConditionVariable(cond);
return 0;
}
#define pthread_cond_wait dav1d_pthread_cond_wait
#define pthread_cond_signal dav1d_pthread_cond_signal
#define pthread_cond_broadcast dav1d_pthread_cond_broadcast
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
#else

View file

@ -85,15 +85,73 @@ COLD int dav1d_pthread_join(pthread_t *const thread, void **const res) {
COLD int dav1d_pthread_once(pthread_once_t *const once_control,
void (*const init_routine)(void))
{
BOOL pending = FALSE;
if (InitOnceBeginInitialize(once_control, 0, &pending, NULL) != TRUE)
return 1;
if (pending == TRUE)
if (InterlockedCompareExchange(once_control, 1, 0) == 0) {
init_routine();
InterlockedExchange(once_control, 2);
} else {
while (InterlockedCompareExchange(once_control, 2, 2) != 2)
Sleep(1);
}
return 0;
}
return !InitOnceComplete(once_control, 0, NULL);
/* Each waiter owns an event. Queue operations and signalling share a lock,
* so a new waiter cannot consume an earlier waiter's notification. */
struct dav1d_cond_waiter {
HANDLE event;
struct dav1d_cond_waiter *next;
};
int dav1d_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
struct dav1d_cond_waiter waiter, **link;
DWORD result;
waiter.event = CreateEventW(NULL, FALSE, FALSE, NULL);
if (!waiter.event) return 1;
EnterCriticalSection(&cond->cs);
waiter.next = NULL;
for (link = &cond->head; *link; link = &(*link)->next) {}
*link = &waiter;
pthread_mutex_unlock(mutex);
LeaveCriticalSection(&cond->cs);
result = WaitForSingleObject(waiter.event, INFINITE);
EnterCriticalSection(&cond->cs);
/* Also unlink on wait failure before the stack record goes away. */
for (link = &cond->head; *link; link = &(*link)->next) {
if (*link == &waiter) {
*link = waiter.next;
break;
}
}
CloseHandle(waiter.event);
LeaveCriticalSection(&cond->cs);
pthread_mutex_lock(mutex);
return result != WAIT_OBJECT_0;
}
int dav1d_pthread_cond_signal(pthread_cond_t *cond) {
int result = 0;
EnterCriticalSection(&cond->cs);
if (cond->head) {
if (SetEvent(cond->head->event)) cond->head = cond->head->next;
else result = 1;
}
LeaveCriticalSection(&cond->cs);
return result;
}
int dav1d_pthread_cond_broadcast(pthread_cond_t *cond) {
int result = 0;
EnterCriticalSection(&cond->cs);
while (cond->head) {
if (!SetEvent(cond->head->event)) {
result = 1;
break;
}
cond->head = cond->head->next;
}
LeaveCriticalSection(&cond->cs);
return result;
}
#endif

View file

@ -47,6 +47,9 @@ if CONFIG['CC_TYPE'] == 'gcc':
OS_LIBS += ['gomp']
if CONFIG['OS_ARCH'] == 'WINNT':
OS_LIBS += ['dl']
elif CONFIG['CLANG_CL']:
# clang-cl lowers OpenMP pragmas to the LLVM OpenMP runtime.
CXXFLAGS += ['-fopenmp']
DEFINES['BUILDING_SOUNDTOUCH'] = 1

View file

@ -39,11 +39,12 @@ if CONFIG['OS_TARGET'] != 'Android':
DEFINES['FAKE_LOG_DEVICE'] = True
SOURCES += [
'system/core/liblog/fake_log_device.c',
# io.h conflicts with the access stub in logd_write.c on Windows.
'system/core/liblog/logprint.c',
]
UNIFIED_SOURCES += [
'system/core/libcutils/strdup16to8.c',
'system/core/liblog/logd_write.c',
'system/core/liblog/logprint.c',
]
EXPORTS.mp4_demuxer += [

View file

@ -26,6 +26,12 @@
#include <assert.h>
#include <arpa/inet.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <log/logd.h>
#include <log/logprint.h>
@ -945,7 +951,11 @@ int android_log_printLogLine(
return -1;
do {
#ifdef _WIN32
ret = _write(fd, outBuffer, totalLen);
#else
ret = write(fd, outBuffer, totalLen);
#endif
} while (ret < 0 && errno == EINTR);
if (ret < 0) {

View file

@ -31,6 +31,15 @@ if CONFIG['INTEL_ARCHITECTURE']:
'inflate_simd.c',
'x86.c',
]
# Clang (including clang-cl) and GCC require explicit ISA flags for
# intrinsics. MSVC accepts these intrinsics without additional flags.
# Keep advanced instructions confined to the runtime-dispatched sources.
if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
SOURCES['adler32_simd.c'].flags += ['-mssse3']
for source in ['crc32_simd.c', 'crc_folding.c']:
SOURCES[source].flags += ['-msse4.2', '-mpclmul']
for source in ['fill_window_sse.c', 'inffast_chunk.c', 'inflate_simd.c']:
SOURCES[source].flags += ['-msse2']
else:
SOURCES += [
'simd_stub.c',

View file

@ -65,8 +65,8 @@ static void _x86_check_features(void)
#include <windows.h>
#include <stdint.h>
static volatile int32_t once_control = 0;
static int fake_pthread_once(volatile int32_t *once_control,
static volatile LONG once_control = 0;
static int fake_pthread_once(volatile LONG *once_control,
void (*init_routine)(void));
void x86_check_features(void)
@ -75,7 +75,7 @@ void x86_check_features(void)
}
/* Copied from "perftools_pthread_once" in tcmalloc */
static int fake_pthread_once(volatile int32_t *once_control,
static int fake_pthread_once(volatile LONG *once_control,
void (*init_routine)(void)) {
// Try for a fast path first. Note: this should be an acquire semantics read
// It is on x86 and x64, where Windows runs.

View file

@ -10,7 +10,6 @@ export CLANG=/c/clang/bin
export CC="clang-cl.exe"
export MT="llvm-mt.exe"
export LD="lld-link.exe"
export LIB="lib.exe"
# Force PATH so UXP thinks only Clang is there
export PATH="$CLANG:$PATH"
@ -24,8 +23,8 @@ mk_add_options MOZ_MAKE_FLAGS="-j6"
ac_add_options --host=x86_64-pc-mingw32
ac_add_options --target=x86_64-pc-mingw32
# Build only Hydra
ac_add_options --enable-application=basilisk
# Build only Dactyloidae
ac_add_options --enable-application=browser
ac_add_options --disable-artifact-builds
# Updater stuffs
@ -43,7 +42,7 @@ ac_add_options --enable-devtools
#ac_add_options --enable-install-strip
ac_add_options --enable-jemalloc
ac_add_options --enable-js-lto
ac_add_options --enable-optimize="-O2 -Ob2ity -openmp -arch:AVX -w0 -w"
ac_add_options --enable-optimize="-O2 -Ob2ity -arch:SSE2 -w0 -w"
ac_add_options --enable-phoenix-extensions
ac_add_options --enable-release
ac_add_options --enable-shared-js
@ -65,7 +64,7 @@ ac_add_options --disable-crashreporter
ac_add_options --disable-eme
ac_add_options --disable-maintenance-service
ac_add_options --disable-parental-controls
ac_add_options --disable-ctypes
ac_add_options --enable-ctypes
mk_add_options MOZ_SERVICES_HEALTHREPORT=0
export CROSS_COMPILE=0
export MOZ_CRASHREPORTER=0

View file

@ -321,8 +321,8 @@ static PRStatus PR_CALLBACK SocketConnectContinue(
} else {
#if defined(_WIN64)
if (fd->secret->overlappedActive) {
PRInt32 rvSent;
if (GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE) == FALSE) {
DWORD rvSent;
if (GetOverlappedResult((HANDLE)osfd, &fd->secret->ol, &rvSent, FALSE) == FALSE) {
err = WSAGetLastError();
PR_LOG(_pr_io_lm, PR_LOG_MIN,
("SocketConnectContinue GetOverlappedResult failed %d\n", err));
@ -353,8 +353,8 @@ static PRStatus PR_CALLBACK SocketConnectContinue(
* To get result we need to use GetOverlappedResult. */
if (fd->secret->overlappedActive) {
PR_ASSERT(fd->secret->nonblocking);
PRInt32 rvSent;
if (GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE) == TRUE) {
DWORD rvSent;
if (GetOverlappedResult((HANDLE)osfd, &fd->secret->ol, &rvSent, FALSE) == TRUE) {
fd->secret->overlappedActive = PR_FALSE;
PR_LOG(_pr_io_lm, PR_LOG_MIN,
("SocketConnectContinue GetOverlappedResult succeeded\n"));

View file

@ -769,10 +769,13 @@ PRStatus _PR_WaitWindowsProcess(PRProcess *process,
return PR_FAILURE;
}
PR_ASSERT(dwRetVal == WAIT_OBJECT_0);
if (exitCode != NULL &&
GetExitCodeProcess(process->md.handle, exitCode) == FALSE) {
PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
return PR_FAILURE;
if (exitCode != NULL) {
DWORD dwExitCode;
if (GetExitCodeProcess(process->md.handle, &dwExitCode) == FALSE) {
PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
return PR_FAILURE;
}
*exitCode = (PRInt32)dwExitCode;
}
CloseHandle(process->md.handle);
PR_DELETE(process);

View file

@ -266,7 +266,7 @@ _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode)
PRInt32
_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
{
PRUint32 bytes;
DWORD bytes;
int rv, err;
rv = ReadFile((HANDLE)fd->secret->md.osfd,
@ -295,7 +295,7 @@ PRInt32
_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
{
PROsfd f = fd->secret->md.osfd;
PRInt32 bytes;
DWORD bytes;
int rv;
rv = WriteFile((HANDLE)f,

View file

@ -7,6 +7,8 @@
*
*/
/* Include Winsock 2 before primpl.h brings in windows.h and Winsock 1. */
#include <winsock2.h>
#include "primpl.h"
#if defined(_WIN64)
@ -117,7 +119,7 @@ _MD_CloseSocket(PROsfd osfd)
PRInt32
_MD_SocketAvailable(PRFileDesc *fd)
{
PRInt32 result;
u_long result;
if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
@ -363,7 +365,7 @@ static PRStatus PR_CALLBACK _pr_set_connectex(void)
{
_pr_win_connectex = NULL;
SOCKET sock;
PRInt32 dwBytes;
DWORD dwBytes;
int rc;
/* Dummy socket needed for WSAIoctl */
@ -445,7 +447,7 @@ _PR_MD_TCPSENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
memset(&fd->secret->ol, 0, sizeof(fd->secret->ol));
/* ConnectEx return TRUE on a success and FALSE on an error. */
if (_pr_win_connectex( (SOCKET)osfd, (struct sockaddr *) addr,
addrlen, buf, amount,
addrlen, (PVOID)buf, amount,
&rvSent, &fd->secret->ol) == TRUE) {
/* When ConnectEx is used, all previously set socket options and
* property are not enabled and to enable them
@ -494,7 +496,7 @@ _PR_MD_TCPSENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
if ( rv < 0 ) {
return -1;
}
rv = GetOverlappedResult(osfd, &fd->secret->ol, &rvSent, FALSE);
rv = GetOverlappedResult((HANDLE)osfd, &fd->secret->ol, &rvSent, FALSE);
if ( rv == TRUE ) {
return rvSent;
} else {

View file

@ -4773,11 +4773,22 @@ if test "$MOZ_TREE_CAIRO"; then
if test "$COMPILE_ENVIRONMENT"; then
MOZ_CHECK_HEADER(d3d9.h, MOZ_ENABLE_D3D9_LAYER=1)
dnl SDK include paths can change between build shells. Do not cache
dnl these checks, or a stale failure disables required D3D exports.
unset ac_cv_header_d3d9_h ac_cv_header_d3d10_h
AC_MSG_CHECKING([for d3d9.h])
AC_TRY_COMPILE([#include <d3d9.h>], ,
[MOZ_ENABLE_D3D9_LAYER=1
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
dnl D3D10 Layers depend on D2D Surfaces.
if test -n "$WIN32_D2D_SURFACE_FEATURE"; then
MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
AC_MSG_CHECKING([for d3d10.h])
AC_TRY_COMPILE([#include <d3d10.h>], ,
[MOZ_ENABLE_D3D10_LAYER=1
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
fi
fi
;;