从我在这里看到的,似乎大多数Windows GDI功能都加速了.例如,如果可用的话,调用BitBlt
或AlphaBlend
使用硬件加速.它还提到窗口的内容仅保存在视频内存中.现在这对于窗口DC来说一切都很好,但是如何使用驻留在显卡内存中的内存DC呢?一旦我们完成了如何获得对像素的直接访问,我认为这将涉及1.临时将数据复制到系统存储器2.改变像素数据3.复制回视频存储器.
我尝试了两种方法,都可以分配系统内存,就像我在任务管理器中看到的那样......
CreateCompatibleBitmap
HDC hDC = GetDC(NULL);
m_hDC = CreateCompatibleDC(hDC);
m_hBmp = CreateCompatibleBitmap(hDC, cx, cy);
ReleaseDC(NULL, hDC);
m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp);
Run Code Online (Sandbox Code Playgroud)
然后调用以获取位
GetBitmapBits(...)
Run Code Online (Sandbox Code Playgroud)
根据各种评论,这确实应该在视频内存中创建兼容的位图,但为什么我仍然可以看到系统内存的增加(即使我不调用GetBitmapBits
)?
CreateDIBSection
HDC hDC = GetDC(NULL);
m_hDC = CreateCompatibleDC(hDC);
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = cx;
bmi.bmiHeader.biHeight = -cy; // top-down
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
m_hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, NULL);
ReleaseDC(NULL, hDC); …
Run Code Online (Sandbox Code Playgroud)好的,我在这里采取一种修改的CRTP路由,以避免虚拟功能查找.但我无法理解它给我的一个错误......
所以我想翻译:
class A
{
public:
static void foo(A *pA)
{
pA->bar();
}
protected:
virtual void bar()
{
TRACE0(_T("A::bar\n"));
}
};
class B : public A
{
protected:
virtual void bar()
{
TRACE0(_T("B::bar\n"));
}
};
Run Code Online (Sandbox Code Playgroud)
按预期工作:
class A
{
public:
template <class T>
static void foo(T *pT)
{
pT->bar();
}
protected:
void bar()
{
TRACE0(_T("A::bar\n"));
}
};
class B : public A
{
protected:
void bar()
{
TRACE0(_T("B::bar\n"));
}
};
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
error C2248: 'B::bar' : cannot access protected …
Run Code Online (Sandbox Code Playgroud) 我花了很多时间为我的类实现移动语义,但现在我正在处理使用它的函数.
好的,所以我有这个对象,它在堆上有很多数据:CLargeOb
为此我实现了移动语义(constructor和operator =).它理想地使用如下:
void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2)
{
SomeOtherFunc(largeOb1); // use objects
SomeOtherFunc(largeOb2);
m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals
m_largeOb2 = (CLargeOb&&)largeOb2;
}
Run Code Online (Sandbox Code Playgroud)
然而,并不总是允许移动/删除对象,所以我添加了这两个函数:
void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2)
{
SomeOtherFunc(largeOb1);
SomeOtherFunc(largeOb2);
m_largeOb1 = largeOb1;
m_largeOb2 = (CLargeOb&&)largeOb2;
}
void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2)
{
SomeOtherFunc(largeOb1);
SomeOtherFunc(largeOb2);
m_largeOb1 = (CLargeOb&&)largeOb1;
m_largeOb2 = largeOb2;
}
Run Code Online (Sandbox Code Playgroud)
虽然它有效但是你已经可以猜到当我有一个将这些对象中的3个或更多作为参数的函数时,它将成为*ss中的一个主要痛苦...是不是有一种聪明的方法来解决这个使用模板或者也许'完美转发'?
我的新应用程序将具有丰富的界面,应该可以动态调整使用透明图标/图像等.对于这个应用程序,我正在尝试决定使用新的Direct2D API对抗旧的GDI.其中一个缺点当然是它不能在XP上运行,尽管我发现有一些更糟糕的问题需要决定:
我注意到在Direct2D环境中输出文本似乎有点模糊(虽然作为一个功能销售).只需查看启用了硬件加速(或IE9)的Firefox 4中的文本.这似乎是因为在Direct2D文本中不像GDI那样遵循(像素)网格.有没有办法强制Direct2D使其坚持像素网格,从而解决这个问题?
速度真的有这么大的提升吗?我试图理解这篇文章,我从中得到的是,在Windows 7和XP(而不是Vista?)中,GDI已经硬件加速了.例如,在我的应用程序中,我使用了很多内存DC,它们刚刚被BitBlt
编入到位,并且正在绘制使用的绘制透明图像/抗锯齿线等AlphaBlend
.最后一个肯定是硬件加速,因为我在测试我的例程时测量速度.
那你要把钱放在哪里?Direct2D是值得的麻烦还是你只是坚持好老的GDI?或者你会推荐别的吗?
注意:我用C++编程btw,没有使用MFC.
我正在尝试构建 VS2010 CRT 库的某些函数的稍微修改的版本,除了尝试访问可能保存指令集架构版本(ISA)的全局变量的部分外,一切都很好:
if (__isa_available > __ISA_AVAILABLE_SSE2)
{
// ...
}
else if (__isa_available == __ISA_AVAILABLE_SSE2)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我在程序集文件中找到了它应该保存的值
__ISA_AVAILABLE_X86 equ 0
__ISA_AVAILABLE_SSE2 equ 1
__ISA_AVAILABLE_SSE42 equ 2
__ISA_AVAILABLE_AVX equ 3
Run Code Online (Sandbox Code Playgroud)
无法找到如何以及在何处__isa_available
分配值(我已尝试在所有目录中查找文件......)
MSDN参考CPUID示例来确定指令集。问题是它使用了__asm
块,而这些块在我的 x64 版本中是不允许的。
有谁知道如何快速分配正确的值__isa_available
?
这可能是一个新手问题,但我只是不知道!要在DLL中使用可能不存在于系统中的函数,我可以使用LoadLibrary
然后使用GetProcAddress
.但是我如何为COM接口做同样的事情呢?我可以包含声明的头文件,IID等等.但我不想使用附带的库链接#pragma comment(lib, "blabla.lib")
.
(我正在尝试使用该WICImagingFactory
接口,这需要链接windowscodecs.lib来编译)
谢谢
在这个答案的启发下,我使用以下解决方案作为只读成员变量:
template <class T, class OWNER>
class readonly
{
friend OWNER;
public:
explicit readonly(const T &t) : m_t(t)
{
}
~readonly()
{
}
operator const T&() const
{
return m_t;
}
private:
T& operator =(const T &t)
{
m_t = t;
return m_t;
}
T m_t;
};
Run Code Online (Sandbox Code Playgroud)
哪个效果很好,为了优化性能,我会像这样使用它:
class A
{
public:
A()
{
}
~A()
{
}
#ifdef _DEBUG // DON'T USE THIS SWITCH, SEE ANSWERS BELOW!
readonly<int, A> m_x, m_y;
#else
int m_x, m_y;
#endif
}; …
Run Code Online (Sandbox Code Playgroud) 我正在读这个,所以我现在正在研究std::forward
和的实现std::move
:
// TEMPLATE FUNCTION forward
template<class _Ty> inline
_Ty&& forward(typename identity<_Ty>::type& _Arg)
{ // forward _Arg, given explicitly specified type parameter
return ((_Ty&&)_Arg);
}
// TEMPLATE FUNCTION move
template<class _Ty> inline
typename tr1::_Remove_reference<_Ty>::_Type&&
move(_Ty&& _Arg)
{ // forward _Arg as movable
return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg);
}
Run Code Online (Sandbox Code Playgroud)
我想我得到了整个故事,但我不理解typename
模板定义(template<...>
)外部的使用.在这种情况下它意味着什么?
这可能是编译器相关的(使用VS2010),或者不是,但为什么以下操作不会调用预期的移动行为:
LargeObject x;
x = SomeFunc(x);
Run Code Online (Sandbox Code Playgroud)
我已将该函数定义为该对
LargeObject SomeFunc(const LargeObject& ob)
{
LargeObject newOb;
// perform operation on new object using old object
return newOb;
}
LargeObject SomeFunc(LargeObject&& ob)
{
// change object directly...
return std::move(ob);
}
Run Code Online (Sandbox Code Playgroud)
我明确需要写
x = SomeFunc(std::move(x));
Run Code Online (Sandbox Code Playgroud)
实现它,我不喜欢......
编辑:第一个使用const-ref的函数是因为我还需要做类似的事情
LargeObject x;
LargeObject y = SomeFunc(x);
Run Code Online (Sandbox Code Playgroud)