Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2018
- 70 participants
- 1549 messages
[PATCH 3/6] quartz/filesource: Don't expose IAMFilterMiscFlags.
by Zebediah Figura
This reverts 9dedc4a795bfbd0ec5c65a3a9d4788875b2ebc09.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/filesource.c | 37 -------------------------------------
dlls/quartz/tests/filesource.c | 1 -
2 files changed, 38 deletions(-)
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 67af560..e5904dc 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -41,7 +41,6 @@ typedef struct AsyncReader
{
BaseFilter filter;
IFileSourceFilter IFileSourceFilter_iface;
- IAMFilterMiscFlags IAMFilterMiscFlags_iface;
IPin * pOutputPin;
LPOLESTR pszFileName;
@@ -63,15 +62,9 @@ static inline AsyncReader *impl_from_IFileSourceFilter(IFileSourceFilter *iface)
return CONTAINING_RECORD(iface, AsyncReader, IFileSourceFilter_iface);
}
-static inline AsyncReader *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
-{
- return CONTAINING_RECORD(iface, AsyncReader, IAMFilterMiscFlags_iface);
-}
-
static const IBaseFilterVtbl AsyncReader_Vtbl;
static const IFileSourceFilterVtbl FileSource_Vtbl;
static const IAsyncReaderVtbl FileAsyncReader_Vtbl;
-static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl;
static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
@@ -432,7 +425,6 @@ HRESULT AsyncReader_create(IUnknown * pUnkOuter, LPVOID * ppv)
BaseFilter_Init(&pAsyncRead->filter, &AsyncReader_Vtbl, &CLSID_AsyncReader, (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter"), &BaseFuncTable);
pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl;
- pAsyncRead->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
pAsyncRead->pOutputPin = NULL;
pAsyncRead->pszFileName = NULL;
@@ -465,8 +457,6 @@ static HRESULT WINAPI AsyncReader_QueryInterface(IBaseFilter * iface, REFIID rii
*ppv = &This->filter.IBaseFilter_iface;
else if (IsEqualIID(riid, &IID_IFileSourceFilter))
*ppv = &This->IFileSourceFilter_iface;
- else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
- *ppv = &This->IAMFilterMiscFlags_iface;
if (*ppv)
{
@@ -1412,30 +1402,3 @@ static const IAsyncReaderVtbl FileAsyncReader_Vtbl =
FileAsyncReader_BeginFlush,
FileAsyncReader_EndFlush,
};
-
-
-static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
- AsyncReader *This = impl_from_IAMFilterMiscFlags(iface);
- return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
-}
-
-static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
- AsyncReader *This = impl_from_IAMFilterMiscFlags(iface);
- return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
-}
-
-static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
- AsyncReader *This = impl_from_IAMFilterMiscFlags(iface);
- return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
-}
-
-static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
- return AM_FILTER_MISC_FLAGS_IS_SOURCE;
-}
-
-static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
- AMFilterMiscFlags_QueryInterface,
- AMFilterMiscFlags_AddRef,
- AMFilterMiscFlags_Release,
- AMFilterMiscFlags_GetMiscFlags
-};
diff --git a/dlls/quartz/tests/filesource.c b/dlls/quartz/tests/filesource.c
index 55c9bf2..b9040e2 100644
--- a/dlls/quartz/tests/filesource.c
+++ b/dlls/quartz/tests/filesource.c
@@ -54,7 +54,6 @@ static void test_interfaces(void)
check_interface(filter, &IID_IBaseFilter, TRUE);
check_interface(filter, &IID_IFileSourceFilter, TRUE);
-todo_wine
check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
check_interface(filter, &IID_IBasicAudio, FALSE);
check_interface(filter, &IID_IBasicVideo, FALSE);
--
2.7.4
Sept. 27, 2018
[PATCH 2/6] quartz/tests/filesource: Test interfaces exposed by the file source filter.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/filesource.c | 53 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/tests/filesource.c b/dlls/quartz/tests/filesource.c
index 15a091b..55c9bf2 100644
--- a/dlls/quartz/tests/filesource.c
+++ b/dlls/quartz/tests/filesource.c
@@ -2,6 +2,7 @@
* File source filter unit tests
*
* Copyright 2016 Sebastian Lackner
+ * Copyright 2018 Zebediah Figura
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,54 @@
#include "dshow.h"
#include "wine/test.h"
+static IBaseFilter *create_file_source(void)
+{
+ IBaseFilter *filter = NULL;
+ HRESULT hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IBaseFilter, (void **)&filter);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ return filter;
+}
+
+#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
+static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
+{
+ IUnknown *iface = iface_ptr;
+ HRESULT hr, expected_hr;
+ IUnknown *unk;
+
+ expected_hr = supported ? S_OK : E_NOINTERFACE;
+
+ hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
+ ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
+ if (SUCCEEDED(hr))
+ IUnknown_Release(unk);
+}
+
+static void test_interfaces(void)
+{
+ IBaseFilter *filter = create_file_source();
+
+ check_interface(filter, &IID_IBaseFilter, TRUE);
+ check_interface(filter, &IID_IFileSourceFilter, TRUE);
+
+todo_wine
+ check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
+ check_interface(filter, &IID_IBasicAudio, FALSE);
+ check_interface(filter, &IID_IBasicVideo, FALSE);
+ check_interface(filter, &IID_IKsPropertySet, FALSE);
+ check_interface(filter, &IID_IMediaPosition, FALSE);
+ check_interface(filter, &IID_IMediaSeeking, FALSE);
+ check_interface(filter, &IID_IPersistPropertyBag, FALSE);
+ check_interface(filter, &IID_IPin, FALSE);
+ check_interface(filter, &IID_IQualityControl, FALSE);
+ check_interface(filter, &IID_IQualProp, FALSE);
+ check_interface(filter, &IID_IReferenceClock, FALSE);
+ check_interface(filter, &IID_IVideoWindow, FALSE);
+
+ IBaseFilter_Release(filter);
+}
+
static void test_file_source_filter(void)
{
static const WCHAR prefix[] = {'w','i','n',0};
@@ -101,8 +150,7 @@ static void test_file_source_filter(void)
ok(ret, "Failed to write file, error %u.\n", GetLastError());
CloseHandle(file);
- CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
- &IID_IBaseFilter, (void **)&filter);
+ filter = create_file_source();
IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
olepath = (void *)0xdeadbeef;
@@ -149,6 +197,7 @@ START_TEST(filesource)
{
CoInitialize(NULL);
+ test_interfaces();
test_file_source_filter();
CoUninitialize();
--
2.7.4
Sept. 27, 2018
[PATCH 1/6] quartz/tests: Move file source filter tests to filesource.c.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/Makefile.in | 1 +
dlls/quartz/tests/avisplitter.c | 132 ----------------------------------
dlls/quartz/tests/filesource.c | 155 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 156 insertions(+), 132 deletions(-)
create mode 100644 dlls/quartz/tests/filesource.c
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in
index 2df9ca1..8ecced9 100644
--- a/dlls/quartz/tests/Makefile.in
+++ b/dlls/quartz/tests/Makefile.in
@@ -4,6 +4,7 @@ IMPORTS = oleaut32 ole32 advapi32 user32
C_SRCS = \
avisplitter.c \
dsoundrender.c \
+ filesource.c \
filtergraph.c \
filtermapper.c \
memallocator.c \
diff --git a/dlls/quartz/tests/avisplitter.c b/dlls/quartz/tests/avisplitter.c
index bc933d1..757b71c 100644
--- a/dlls/quartz/tests/avisplitter.c
+++ b/dlls/quartz/tests/avisplitter.c
@@ -139,137 +139,6 @@ static void test_basefilter(void)
IBaseFilter_Release(base);
}
-static void test_filesourcefilter(void)
-{
- static const WCHAR prefix[] = {'w','i','n',0};
- static const struct
- {
- const char *label;
- const char *data;
- DWORD size;
- const GUID *subtype;
- }
- tests[] =
- {
- {
- "AVI",
- "\x52\x49\x46\x46xxxx\x41\x56\x49\x20",
- 12,
- &MEDIASUBTYPE_Avi,
- },
- {
- "MPEG1 System",
- "\x00\x00\x01\xBA\x21\x00\x01\x00\x01\x80\x00\x01\x00\x00\x01\xBB",
- 16,
- &MEDIASUBTYPE_MPEG1System,
- },
- {
- "MPEG1 Video",
- "\x00\x00\x01\xB3",
- 4,
- &MEDIASUBTYPE_MPEG1Video,
- },
- {
- "MPEG1 Audio",
- "\xFF\xE0",
- 2,
- &MEDIASUBTYPE_MPEG1Audio,
- },
- {
- "MPEG2 Program",
- "\x00\x00\x01\xBA\x40",
- 5,
- &MEDIASUBTYPE_MPEG2_PROGRAM,
- },
- {
- "WAVE",
- "\x52\x49\x46\x46xxxx\x57\x41\x56\x45",
- 12,
- &MEDIASUBTYPE_WAVE,
- },
- {
- "unknown format",
- "Hello World",
- 11,
- NULL, /* FIXME: should be &MEDIASUBTYPE_NULL */
- },
- };
- WCHAR path[MAX_PATH], temp[MAX_PATH];
- IFileSourceFilter *filesource;
- DWORD ret, written;
- IBaseFilter *base;
- AM_MEDIA_TYPE mt;
- OLECHAR *olepath;
- BOOL success;
- HANDLE file;
- HRESULT hr;
- int i;
-
- ret = GetTempPathW(MAX_PATH, temp);
- ok(ret, "GetTempPathW failed with error %u\n", GetLastError());
- ret = GetTempFileNameW(temp, prefix, 0, path);
- ok(ret, "GetTempFileNameW failed with error %u\n", GetLastError());
-
- for (i = 0; i < ARRAY_SIZE(tests); i++)
- {
- trace("Running test for %s\n", tests[i].label);
-
- file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- ok(file != INVALID_HANDLE_VALUE, "CreateFileW failed with error %u\n", GetLastError());
- success = WriteFile(file, tests[i].data, tests[i].size, &written, NULL);
- ok(success, "WriteFile failed with error %u\n", GetLastError());
- ok(written == tests[i].size, "could not write test data\n");
- CloseHandle(file);
-
- hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
- &IID_IBaseFilter, (void **)&base);
- ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
- hr = IBaseFilter_QueryInterface(base, &IID_IFileSourceFilter, (void **)&filesource);
- ok(hr == S_OK, "IBaseFilter_QueryInterface failed with %08x\n", hr);
-
- olepath = (void *)0xdeadbeef;
- hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL);
- ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
- ok(olepath == NULL, "expected NULL, got %p\n", olepath);
-
- hr = IFileSourceFilter_Load(filesource, NULL, NULL);
- ok(hr == E_POINTER, "expected E_POINTER, got %08x\n", hr);
-
- hr = IFileSourceFilter_Load(filesource, path, NULL);
- ok(hr == S_OK, "IFileSourceFilter_Load failed with %08x\n", hr);
-
- hr = IFileSourceFilter_GetCurFile(filesource, NULL, &mt);
- ok(hr == E_POINTER, "expected E_POINTER, got %08x\n", hr);
-
- olepath = NULL;
- hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL);
- ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
- CoTaskMemFree(olepath);
-
- olepath = NULL;
- memset(&mt, 0x11, sizeof(mt));
- hr = IFileSourceFilter_GetCurFile(filesource, &olepath, &mt);
- ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
- ok(!lstrcmpW(olepath, path),
- "expected %s, got %s\n", wine_dbgstr_w(path), wine_dbgstr_w(olepath));
- if (tests[i].subtype)
- {
- ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream),
- "expected MEDIATYPE_Stream, got %s\n", wine_dbgstr_guid(&mt.majortype));
- ok(IsEqualGUID(&mt.subtype, tests[i].subtype),
- "expected %s, got %s\n", wine_dbgstr_guid(tests[i].subtype), wine_dbgstr_guid(&mt.subtype));
- }
- CoTaskMemFree(olepath);
-
- IFileSourceFilter_Release(filesource);
- IBaseFilter_Release(base);
-
- success = DeleteFileW(path);
- ok(success, "DeleteFileW failed with error %u\n", GetLastError());
- }
-}
-
static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0};
static WCHAR *load_resource(const WCHAR *name)
@@ -557,7 +426,6 @@ START_TEST(avisplitter)
test_query_interface();
test_basefilter();
- test_filesourcefilter();
test_filter_graph();
release_avisplitter();
diff --git a/dlls/quartz/tests/filesource.c b/dlls/quartz/tests/filesource.c
new file mode 100644
index 0000000..15a091b
--- /dev/null
+++ b/dlls/quartz/tests/filesource.c
@@ -0,0 +1,155 @@
+/*
+ * File source filter unit tests
+ *
+ * Copyright 2016 Sebastian Lackner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include "dshow.h"
+#include "wine/test.h"
+
+static void test_file_source_filter(void)
+{
+ static const WCHAR prefix[] = {'w','i','n',0};
+ static const struct
+ {
+ const char *label;
+ const char *data;
+ DWORD size;
+ const GUID *subtype;
+ }
+ tests[] =
+ {
+ {
+ "AVI",
+ "\x52\x49\x46\x46xxxx\x41\x56\x49\x20",
+ 12,
+ &MEDIASUBTYPE_Avi,
+ },
+ {
+ "MPEG1 System",
+ "\x00\x00\x01\xBA\x21\x00\x01\x00\x01\x80\x00\x01\x00\x00\x01\xBB",
+ 16,
+ &MEDIASUBTYPE_MPEG1System,
+ },
+ {
+ "MPEG1 Video",
+ "\x00\x00\x01\xB3",
+ 4,
+ &MEDIASUBTYPE_MPEG1Video,
+ },
+ {
+ "MPEG1 Audio",
+ "\xFF\xE0",
+ 2,
+ &MEDIASUBTYPE_MPEG1Audio,
+ },
+ {
+ "MPEG2 Program",
+ "\x00\x00\x01\xBA\x40",
+ 5,
+ &MEDIASUBTYPE_MPEG2_PROGRAM,
+ },
+ {
+ "WAVE",
+ "\x52\x49\x46\x46xxxx\x57\x41\x56\x45",
+ 12,
+ &MEDIASUBTYPE_WAVE,
+ },
+ {
+ "unknown format",
+ "Hello World",
+ 11,
+ NULL, /* FIXME: should be &MEDIASUBTYPE_NULL */
+ },
+ };
+ WCHAR path[MAX_PATH], temp[MAX_PATH];
+ IFileSourceFilter *filesource;
+ IBaseFilter *filter;
+ AM_MEDIA_TYPE mt;
+ OLECHAR *olepath;
+ DWORD written;
+ HANDLE file;
+ HRESULT hr;
+ BOOL ret;
+ int i;
+
+ GetTempPathW(MAX_PATH, temp);
+ GetTempFileNameW(temp, prefix, 0, path);
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ trace("Running test for %s.\n", tests[i].label);
+
+ file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "Failed to create file, error %u.\n", GetLastError());
+ ret = WriteFile(file, tests[i].data, tests[i].size, &written, NULL);
+ ok(ret, "Failed to write file, error %u.\n", GetLastError());
+ CloseHandle(file);
+
+ CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IBaseFilter, (void **)&filter);
+ IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
+
+ olepath = (void *)0xdeadbeef;
+ hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(!olepath, "Got path %s.\n", wine_dbgstr_w(olepath));
+
+ hr = IFileSourceFilter_Load(filesource, NULL, NULL);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+
+ hr = IFileSourceFilter_Load(filesource, path, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IFileSourceFilter_GetCurFile(filesource, NULL, &mt);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+
+ olepath = NULL;
+ hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ CoTaskMemFree(olepath);
+
+ olepath = NULL;
+ memset(&mt, 0x11, sizeof(mt));
+ hr = IFileSourceFilter_GetCurFile(filesource, &olepath, &mt);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(!lstrcmpW(olepath, path), "Expected path %s, got %s.\n",
+ wine_dbgstr_w(path), wine_dbgstr_w(olepath));
+ ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Stream), "Got major type %s.\n",
+ wine_dbgstr_guid(&mt.majortype));
+ if (tests[i].subtype)
+ ok(IsEqualGUID(&mt.subtype, tests[i].subtype), "Expected subtype %s, got %s.\n",
+ wine_dbgstr_guid(tests[i].subtype), wine_dbgstr_guid(&mt.subtype));
+ CoTaskMemFree(olepath);
+
+ IFileSourceFilter_Release(filesource);
+ IBaseFilter_Release(filter);
+
+ ret = DeleteFileW(path);
+ ok(ret, "Failed to delete file, error %u\n", GetLastError());
+ }
+}
+
+START_TEST(filesource)
+{
+ CoInitialize(NULL);
+
+ test_file_source_filter();
+
+ CoUninitialize();
+}
--
2.7.4
Sept. 27, 2018
[PATCH v3 6/6] shell32/autocomplete: Hide the auto-suggest listbox when ESC is pressed
by Gabriel Ivăncescu
When the listbox is visible, ESC should hide it. Only when it's not visible
should it be forwarded to the edit control. This matches Windows behavior.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
no_fwd_char is needed because we cannot send an ESC character in WM_CHAR
to the edit control, which clears the text. We have to handle it in KeyDown
though, just like VK_RETURN in previous patch.
dlls/shell32/autocomplete.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index d4bc8b1..f650bf2 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -346,6 +346,15 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
{
switch (wParam)
{
+ case VK_ESCAPE:
+ /* When pressing ESC, Windows hides the auto-suggest listbox, if visible */
+ if ((ac->options & ACO_AUTOSUGGEST) && IsWindowVisible(ac->hwndListBox))
+ {
+ ShowWindow(ac->hwndListBox, SW_HIDE);
+ ac->no_fwd_char = 0x1B; /* ESC char */
+ return 0;
+ }
+ break;
case VK_RETURN:
/* If quickComplete is set and control is pressed, replace the string */
if (ac->quickComplete && (GetKeyState(VK_CONTROL) & 0x8000))
--
1.9.1
Sept. 26, 2018
[PATCH v3 5/6] shell32/autocomplete: Fix handling of Return key when an auto-suggestion item is selected
by Gabriel Ivăncescu
When selecting an item from the AutoComplete's listbox, the Return key
should act the same as a left click on it (place the text, select it,
and hide the listbox). This matches Windows behavior.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
Also fixes quickComplete since a VK_RETURN is sent as a WM_CHAR of '\n'
when CTRL is pressed and it must not be forwarded in WM_CHAR. Furthermore,
we have to process this in WM_KEYDOWN to ensure correct behavior.
The problem isn't the autocompletion here, but rather the edit control,
which must not receive that character at all.
no_fwd_char is also needed for future patches (and even the next patch)
to suppress forwarding the respective char from the KeyDown (for example,
when ACO_USETAB will be implemented).
dlls/shell32/autocomplete.c | 39 +++++++++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index d9b109d..d4bc8b1 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -69,6 +69,7 @@ typedef struct
LONG ref;
BYTE initialized : 1;
BYTE enabled : 1;
+ UCHAR no_fwd_char;
AUTOCOMPLETEOPTIONS options;
HWND hwndEdit;
HWND hwndListBox;
@@ -134,6 +135,34 @@ static size_t format_quick_complete(WCHAR *dst, const WCHAR *qc, const WCHAR *st
return dst - base;
}
+static BOOL select_item_with_return_key(IAutoCompleteImpl *ac, HWND hwnd)
+{
+ WCHAR *text;
+ HWND hwndListBox = ac->hwndListBox;
+ if (!(ac->options & ACO_AUTOSUGGEST))
+ return FALSE;
+
+ if (IsWindowVisible(hwndListBox))
+ {
+ INT sel = SendMessageW(hwndListBox, LB_GETCURSEL, 0, 0);
+ if (sel >= 0)
+ {
+ UINT len = SendMessageW(hwndListBox, LB_GETTEXTLEN, sel, 0);
+ if ((text = heap_alloc((len + 1) * sizeof(WCHAR))))
+ {
+ len = SendMessageW(hwndListBox, LB_GETTEXT, sel, (LPARAM)text);
+ set_text_and_selection(ac, hwnd, text, 0, len);
+ ShowWindow(hwndListBox, SW_HIDE);
+ ac->no_fwd_char = '\r'; /* RETURN char */
+ heap_free(text);
+ return TRUE;
+ }
+ }
+ }
+ ShowWindow(hwndListBox, SW_HIDE);
+ return FALSE;
+}
+
static LRESULT change_selection(IAutoCompleteImpl *ac, HWND hwnd, UINT key)
{
INT count = SendMessageW(ac->hwndListBox, LB_GETCOUNT, 0, 0);
@@ -324,6 +353,8 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
WCHAR *text, *buf;
size_t sz;
UINT len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
+ ac->no_fwd_char = '\n'; /* CTRL+RETURN char */
+
if (!(text = heap_alloc((len + 1) * sizeof(WCHAR))))
return 0;
len = SendMessageW(hwnd, WM_GETTEXT, len + 1, (LPARAM)text);
@@ -342,8 +373,8 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
return 0;
}
- if (ac->options & ACO_AUTOSUGGEST)
- ShowWindow(ac->hwndListBox, SW_HIDE);
+ if (select_item_with_return_key(ac, hwnd))
+ return 0;
break;
case VK_UP:
case VK_DOWN:
@@ -375,6 +406,7 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
return ret;
}
}
+ ac->no_fwd_char = '\0';
return CallWindowProcW(ac->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}
@@ -404,6 +436,9 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
return ACEditSubclassProc_KeyDown(This, hwnd, uMsg, wParam, lParam);
case WM_CHAR:
case WM_UNICHAR:
+ if (wParam == This->no_fwd_char) return 0;
+ This->no_fwd_char = '\0';
+
/* Don't autocomplete at all on most control characters */
if (iscntrlW(wParam) && !(wParam >= '\b' && wParam <= '\r'))
break;
--
1.9.1
Sept. 26, 2018
[PATCH v3 4/6] shell32/autocomplete: Re-arrange some fields for better packing
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
v3: Use bitfield for future expansion.
dlls/shell32/autocomplete.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 5cf63fe..d9b109d 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -67,8 +67,9 @@ typedef struct
IAutoComplete2 IAutoComplete2_iface;
IAutoCompleteDropDown IAutoCompleteDropDown_iface;
LONG ref;
- BOOL initialized;
- BOOL enabled;
+ BYTE initialized : 1;
+ BYTE enabled : 1;
+ AUTOCOMPLETEOPTIONS options;
HWND hwndEdit;
HWND hwndListBox;
WNDPROC wpOrigEditProc;
@@ -76,7 +77,6 @@ typedef struct
WCHAR *txtbackup;
WCHAR *quickComplete;
IEnumString *enumstr;
- AUTOCOMPLETEOPTIONS options;
} IAutoCompleteImpl;
enum autoappend_flag
--
1.9.1
Sept. 26, 2018
[PATCH v3 3/6] shell32/autocomplete: Implement PageDown and PageUp for the auto-suggest listbox
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
It's meant to be the same as on Windows; these keys always go to the visible
bottom or top of the list, unless the selection is already there in which
case they scroll by one page.
However, when wrapping around, they go through txtbackup just like the
arrow keys. The logic for the arrow keys has not been changed.
PageDown/PageUp also do work with ACO_UPDOWNKEYDROPSLIST on Windows (they
show the listbox).
dlls/shell32/autocomplete.c | 93 ++++++++++++++++++++++++++++++---------------
1 file changed, 63 insertions(+), 30 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 621c5fd..5cf63fe 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -134,6 +134,66 @@ static size_t format_quick_complete(WCHAR *dst, const WCHAR *qc, const WCHAR *st
return dst - base;
}
+static LRESULT change_selection(IAutoCompleteImpl *ac, HWND hwnd, UINT key)
+{
+ INT count = SendMessageW(ac->hwndListBox, LB_GETCOUNT, 0, 0);
+ INT sel = SendMessageW(ac->hwndListBox, LB_GETCURSEL, 0, 0);
+ if (key == VK_PRIOR || key == VK_NEXT)
+ {
+ if (sel < 0)
+ sel = (key == VK_PRIOR) ? count - 1 : 0;
+ else
+ {
+ INT base = SendMessageW(ac->hwndListBox, LB_GETTOPINDEX, 0, 0);
+ INT pgsz = SendMessageW(ac->hwndListBox, LB_GETLISTBOXINFO, 0, 0);
+ pgsz = max(pgsz - 1, 1);
+ if (key == VK_PRIOR)
+ {
+ if (sel == 0)
+ sel = -1;
+ else
+ {
+ if (sel == base) base -= min(base, pgsz);
+ sel = base;
+ }
+ }
+ else
+ {
+ if (sel == count - 1)
+ sel = -1;
+ else
+ {
+ base += pgsz;
+ if (sel >= base) base += pgsz;
+ sel = min(base, count - 1);
+ }
+ }
+ }
+ }
+ else if (key == VK_UP)
+ sel = ((sel - 1) < -1) ? count - 1 : sel - 1;
+ else
+ sel = ((sel + 1) >= count) ? -1 : sel + 1;
+
+ SendMessageW(ac->hwndListBox, LB_SETCURSEL, sel, 0);
+ if (sel >= 0)
+ {
+ WCHAR *msg;
+ UINT len = SendMessageW(ac->hwndListBox, LB_GETTEXTLEN, sel, 0);
+ if (!(msg = heap_alloc((len + 1) * sizeof(WCHAR))))
+ return 0;
+ len = SendMessageW(ac->hwndListBox, LB_GETTEXT, sel, (LPARAM)msg);
+ set_text_and_selection(ac, hwnd, msg, len, len);
+ heap_free(msg);
+ }
+ else
+ {
+ UINT len = strlenW(ac->txtbackup);
+ set_text_and_selection(ac, hwnd, ac->txtbackup, len, len);
+ }
+ return 0;
+}
+
static void autoappend_str(IAutoCompleteImpl *ac, WCHAR *text, UINT len, WCHAR *str, HWND hwnd)
{
DWORD sel_start;
@@ -287,6 +347,8 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
break;
case VK_UP:
case VK_DOWN:
+ case VK_PRIOR:
+ case VK_NEXT:
/* Two cases here:
- if the listbox is not visible and ACO_UPDOWNKEYDROPSLIST is
set, display it with all the entries, without selecting any
@@ -304,36 +366,7 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
}
}
else
- {
- INT count, sel;
- count = SendMessageW(ac->hwndListBox, LB_GETCOUNT, 0, 0);
-
- /* Change the selection */
- sel = SendMessageW(ac->hwndListBox, LB_GETCURSEL, 0, 0);
- if (wParam == VK_UP)
- sel = ((sel - 1) < -1) ? count - 1 : sel - 1;
- else
- sel = ((sel + 1) >= count) ? -1 : sel + 1;
- SendMessageW(ac->hwndListBox, LB_SETCURSEL, sel, 0);
- if (sel >= 0)
- {
- WCHAR *msg;
- UINT len;
-
- len = SendMessageW(ac->hwndListBox, LB_GETTEXTLEN, sel, 0);
- if (!(msg = heap_alloc((len + 1) * sizeof(WCHAR))))
- return 0;
- len = SendMessageW(ac->hwndListBox, LB_GETTEXT, sel, (LPARAM)msg);
- set_text_and_selection(ac, hwnd, msg, len, len);
- heap_free(msg);
- }
- else
- {
- UINT len = strlenW(ac->txtbackup);
- set_text_and_selection(ac, hwnd, ac->txtbackup, len, len);
- }
- return 0;
- }
+ return change_selection(ac, hwnd, wParam);
break;
case VK_DELETE:
{
--
1.9.1
Sept. 26, 2018
[PATCH v3 2/6] shell32/autocomplete: Don't auto-append unless the caret is at the end
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
This gets rid of annoying caret movement when replacing a selection that's
not at the end (so it matches Windows).
dlls/shell32/autocomplete.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 9acd3f4..621c5fd 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -136,9 +136,15 @@ static size_t format_quick_complete(WCHAR *dst, const WCHAR *qc, const WCHAR *st
static void autoappend_str(IAutoCompleteImpl *ac, WCHAR *text, UINT len, WCHAR *str, HWND hwnd)
{
+ DWORD sel_start;
WCHAR *tmp;
size_t size;
+ /* Don't auto-append unless the caret is at the end */
+ SendMessageW(hwnd, EM_GETSEL, (WPARAM)&sel_start, 0);
+ if (sel_start != len)
+ return;
+
/* The character capitalization can be different,
so merge text and str into a new string */
size = len + strlenW(&str[len]) + 1;
--
1.9.1
Sept. 26, 2018
[PATCH v3 1/6] shell32/autocomplete: Use the same font for the AutoComplete listbox as the edit control
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
This looks much nicer and less out of place.
v3: Use SendMessage.
dlls/shell32/autocomplete.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index fe5bba2..9acd3f4 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -384,6 +384,10 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
ret = CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
autocomplete_text(This, hwnd, autoappend_flag_yes);
return ret;
+ case WM_SETFONT:
+ if (This->hwndListBox)
+ SendMessageW(This->hwndListBox, WM_SETFONT, wParam, lParam);
+ break;
case WM_DESTROY:
{
WNDPROC proc = This->wpOrigEditProc;
@@ -434,9 +438,16 @@ static void create_listbox(IAutoCompleteImpl *This)
0, 0, 0, 0, GetParent(This->hwndEdit), NULL, shell32_hInstance, NULL);
if (This->hwndListBox) {
+ HFONT edit_font;
+
This->wpOrigLBoxProc = (WNDPROC) SetWindowLongPtrW( This->hwndListBox, GWLP_WNDPROC, (LONG_PTR) ACLBoxSubclassProc);
SetWindowLongPtrW( This->hwndListBox, GWLP_USERDATA, (LONG_PTR)This);
SetParent(This->hwndListBox, HWND_DESKTOP);
+
+ /* Use the same font as the edit control, as it gets destroyed before it anyway */
+ edit_font = (HFONT)SendMessageW(This->hwndEdit, WM_GETFONT, 0, 0);
+ if (edit_font)
+ SendMessageW(This->hwndListBox, WM_SETFONT, (WPARAM)edit_font, FALSE);
}
else
This->options &= ~ACO_AUTOSUGGEST;
--
1.9.1
Sept. 26, 2018
[PATCH v2] wined3d: Use query buffer objects for occlusion queries.
by Andrew Wesie
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45723
Signed-off-by: Andrew Wesie <awesie(a)gmail.com>
---
v2: Remove QUERY_INVALID_VALUE. Instead, use two elements of results buffer.
Initialize the elements to different values, then update both of them with
the query result. Once the elements are equal, we know that we have the
result.
dlls/wined3d/adapter_gl.c | 6 ++
dlls/wined3d/query.c | 166 ++++++++++++++++++++++++++++++++++++-----
dlls/wined3d/wined3d_gl.h | 2 +
dlls/wined3d/wined3d_private.h | 3 +
4 files changed, 158 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 1722438..23462cf 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -58,6 +58,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
/* ARB */
{"GL_ARB_base_instance", ARB_BASE_INSTANCE },
{"GL_ARB_blend_func_extended", ARB_BLEND_FUNC_EXTENDED },
+ {"GL_ARB_buffer_storage", ARB_BUFFER_STORAGE },
{"GL_ARB_clear_buffer_object", ARB_CLEAR_BUFFER_OBJECT },
{"GL_ARB_clear_texture", ARB_CLEAR_TEXTURE },
{"GL_ARB_clip_control", ARB_CLIP_CONTROL },
@@ -103,6 +104,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
{"GL_ARB_point_parameters", ARB_POINT_PARAMETERS },
{"GL_ARB_point_sprite", ARB_POINT_SPRITE },
{"GL_ARB_provoking_vertex", ARB_PROVOKING_VERTEX },
+ {"GL_ARB_query_buffer_object", ARB_QUERY_BUFFER_OBJECT },
{"GL_ARB_sample_shading", ARB_SAMPLE_SHADING },
{"GL_ARB_sampler_objects", ARB_SAMPLER_OBJECTS },
{"GL_ARB_seamless_cube_map", ARB_SEAMLESS_CUBE_MAP },
@@ -2061,6 +2063,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
/* GL_ARB_blend_func_extended */
USE_GL_FUNC(glBindFragDataLocationIndexed)
USE_GL_FUNC(glGetFragDataIndex)
+ /* GL_ARB_buffer_storage */
+ USE_GL_FUNC(glBufferStorage)
/* GL_ARB_clear_buffer_object */
USE_GL_FUNC(glClearBufferData)
USE_GL_FUNC(glClearBufferSubData)
@@ -3302,7 +3306,9 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
{ARB_TEXTURE_STORAGE_MULTISAMPLE, MAKEDWORD_VERSION(4, 2)},
{ARB_TEXTURE_VIEW, MAKEDWORD_VERSION(4, 3)},
+ {ARB_BUFFER_STORAGE, MAKEDWORD_VERSION(4, 4)},
{ARB_CLEAR_TEXTURE, MAKEDWORD_VERSION(4, 4)},
+ {ARB_QUERY_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 4)},
{ARB_CLIP_CONTROL, MAKEDWORD_VERSION(4, 5)},
{ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)},
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 01e6bcb..607709e 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -25,6 +25,115 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+static void wined3d_query_buffer_invalidate(struct wined3d_query *query)
+{
+ /* map[0] != map[1]: exact values do not have any significance. */
+ query->map_ptr[0] = 0;
+ query->map_ptr[1] = ~0;
+}
+
+static void wined3d_query_create_buffer_object(struct wined3d_context *context, struct wined3d_query *query)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const GLuint map_flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
+ GLuint buffer_object;
+
+ if (!gl_info->supported[ARB_BUFFER_STORAGE])
+ return;
+
+ GL_EXTCALL(glGenBuffers(1, &buffer_object));
+ checkGLcall("glGenBuffers");
+
+ GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, buffer_object));
+ checkGLcall("glBindBuffer");
+
+ GL_EXTCALL(glBufferStorage(GL_QUERY_BUFFER, sizeof(query->map_ptr[0]) * 2, NULL, map_flags));
+ checkGLcall("glBufferStorage");
+
+ query->map_ptr = GL_EXTCALL(glMapBufferRange(GL_QUERY_BUFFER, 0, sizeof(query->map_ptr[0]) * 2, map_flags));
+ checkGLcall("glMapBufferRange");
+
+ GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, 0));
+
+ wined3d_query_buffer_invalidate(query);
+ query->buffer_object = buffer_object;
+}
+
+static void wined3d_query_destroy_buffer_object(struct wined3d_context *context, struct wined3d_query *query)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ GL_EXTCALL(glDeleteBuffers(1, &query->buffer_object));
+ checkGLcall("glDeleteBuffers");
+
+ query->buffer_object = 0;
+ query->map_ptr = NULL;
+}
+
+static void wined3d_query_buffer_begin(struct wined3d_query *query)
+{
+ if (query->buffer_object)
+ wined3d_query_buffer_invalidate(query);
+}
+
+static void wined3d_query_buffer_begin_cs(struct wined3d_context *context, struct wined3d_query *query)
+{
+ if (!context->gl_info->supported[ARB_QUERY_BUFFER_OBJECT])
+ return;
+
+ if (!query->buffer_object)
+ wined3d_query_create_buffer_object(context, query);
+}
+
+static BOOL wined3d_query_buffer_end_cs(struct wined3d_context *context, struct wined3d_query *query, GLuint id)
+{
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+
+ if (!query->buffer_object)
+ return FALSE;
+
+ GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, query->buffer_object));
+ checkGLcall("glBindBuffer");
+
+ /* Read the same value twice. We know we have the result if map[0] == map[1]. */
+ GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, (void *)0));
+ GL_EXTCALL(glGetQueryObjectui64v(id, GL_QUERY_RESULT, (void *)sizeof(query->map_ptr[0])));
+ checkGLcall("glGetQueryObjectui64v");
+
+ GL_EXTCALL(glBindBuffer(GL_QUERY_BUFFER, 0));
+ return TRUE;
+}
+
+static BOOL wined3d_query_buffer_poll(struct wined3d_query *query, GLuint *available, UINT64 *result)
+{
+ if (!query->buffer_object)
+ return FALSE;
+
+ if (query->map_ptr && query->map_ptr[0] == query->map_ptr[1])
+ {
+ if (available)
+ *available = GL_TRUE;
+ if (result)
+ *result = query->map_ptr[0];
+ }
+ else
+ {
+ if (available)
+ *available = GL_FALSE;
+ }
+ return TRUE;
+}
+
+static BOOL wined3d_query_buffer_get_data(struct wined3d_query *query, DWORD flags)
+{
+ if (!query->buffer_object)
+ return FALSE;
+
+ if (flags & WINED3DGETDATA_FLUSH && query->device->cs->thread && !query->device->cs->queries_flushed)
+ wined3d_cs_emit_flush(query->device->cs);
+ return TRUE;
+}
+
static UINT64 get_query_result64(GLuint id, const struct wined3d_gl_info *gl_info)
{
if (gl_info->supported[ARB_TIMER_QUERY])
@@ -339,6 +448,14 @@ static void wined3d_query_destroy_object(void *object)
if (!list_empty(&query->poll_list_entry))
list_remove(&query->poll_list_entry);
+ if (query->buffer_object)
+ {
+ struct wined3d_context *context;
+ context = context_acquire(query->device, NULL, 0);
+ wined3d_query_destroy_buffer_object(context, query);
+ context_release(context);
+ }
+
/* Queries are specific to the GL context that created them. Not
* deleting the query will obviously leak it, but that's still better
* than potentially deleting a different query with the same id in this
@@ -382,7 +499,7 @@ HRESULT CDECL wined3d_query_get_data(struct wined3d_query *query,
return WINED3DERR_INVALIDCALL;
}
- if (!query->device->cs->thread)
+ if (!query->device->cs->thread || wined3d_query_buffer_get_data(query, flags))
{
if (!query->query_ops->query_poll(query, flags))
return S_FALSE;
@@ -411,6 +528,9 @@ HRESULT CDECL wined3d_query_issue(struct wined3d_query *query, DWORD flags)
{
TRACE("query %p, flags %#x.\n", query, flags);
+ if (flags & WINED3DISSUE_BEGIN)
+ wined3d_query_buffer_begin(query);
+
if (flags & WINED3DISSUE_END)
++query->counter_main;
@@ -428,31 +548,35 @@ static BOOL wined3d_occlusion_query_ops_poll(struct wined3d_query *query, DWORD
{
struct wined3d_occlusion_query *oq = wined3d_occlusion_query_from_query(query);
struct wined3d_device *device = query->device;
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
- GLuint available;
+ GLuint available = FALSE;
TRACE("query %p, flags %#x.\n", query, flags);
- if (!(context = context_reacquire(device, oq->context)))
+ if (!wined3d_query_buffer_poll(query, &available, &oq->samples))
{
- FIXME("%p Wrong thread, returning 1.\n", query);
- oq->samples = 1;
- return TRUE;
- }
- gl_info = context->gl_info;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
- GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
- TRACE("Available %#x.\n", available);
+ if (!(context = context_reacquire(device, oq->context)))
+ {
+ FIXME("%p Wrong thread, returning 1.\n", query);
+ oq->samples = 1;
+ return TRUE;
+ }
+ gl_info = context->gl_info;
- if (available)
- {
- oq->samples = get_query_result64(oq->id, gl_info);
- TRACE("Returning 0x%s samples.\n", wine_dbgstr_longlong(oq->samples));
+ GL_EXTCALL(glGetQueryObjectuiv(oq->id, GL_QUERY_RESULT_AVAILABLE, &available));
+ TRACE("Available %#x.\n", available);
+
+ if (available)
+ oq->samples = get_query_result64(oq->id, gl_info);
+
+ checkGLcall("poll occlusion query");
+ context_release(context);
}
- checkGLcall("poll occlusion query");
- context_release(context);
+ if (available)
+ TRACE("Returning 0x%s samples.\n", wine_dbgstr_longlong(oq->samples));
return available;
}
@@ -564,6 +688,8 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD
GL_EXTCALL(glBeginQuery(GL_SAMPLES_PASSED, oq->id));
checkGLcall("glBeginQuery()");
+ wined3d_query_buffer_begin_cs(context, query);
+
context_release(context);
oq->started = TRUE;
}
@@ -580,8 +706,10 @@ static BOOL wined3d_occlusion_query_ops_issue(struct wined3d_query *query, DWORD
GL_EXTCALL(glEndQuery(GL_SAMPLES_PASSED));
checkGLcall("glEndQuery()");
+ /* If we cannot use query buffers, poll instead. */
+ poll = !wined3d_query_buffer_end_cs(context, query, oq->id);
+
context_release(context);
- poll = TRUE;
}
else
{
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 06aa21c..2a985da 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -44,6 +44,7 @@ enum wined3d_gl_extension
/* ARB */
ARB_BASE_INSTANCE,
ARB_BLEND_FUNC_EXTENDED,
+ ARB_BUFFER_STORAGE,
ARB_CLEAR_BUFFER_OBJECT,
ARB_CLEAR_TEXTURE,
ARB_CLIP_CONTROL,
@@ -89,6 +90,7 @@ enum wined3d_gl_extension
ARB_POINT_PARAMETERS,
ARB_POINT_SPRITE,
ARB_PROVOKING_VERTEX,
+ ARB_QUERY_BUFFER_OBJECT,
ARB_SAMPLE_SHADING,
ARB_SAMPLER_OBJECTS,
ARB_SEAMLESS_CUBE_MAP,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 40a27ff..4508764 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1729,6 +1729,9 @@ struct wined3d_query
LONG counter_main, counter_retrieved;
struct list poll_list_entry;
+
+ GLuint buffer_object;
+ UINT64 *map_ptr;
};
struct wined3d_event_query
--
2.7.4
Sept. 26, 2018