WPFの描画

[戻る]
dicson 2011/04/11(月) 21:56:36
http://d.hatena.ne.jp/NyaRuRu/20070127/p2

このブログで紹介されている方法でメモリを見てみたのですが、
Windows7ではメモリマッピングが見つかりません。

WPFでは直接ここに書き込んでいるそうですが、そのアドレスを調べる関数はありますか?
また、ない場合どのようにして取得するのでしょうか?

gak 2011/04/12(火) 12:32:22
> Windows7ではメモリマッピングが見つかりません
Windows7には無い。Vistaが無駄にメモリ喰いまくってた因の一つがコイツなので流石に
改善された。
http://blogs.msdn.com/b/e7/archive/2009/04/25/engineering-windows-7-for-graphics-performance.aspx
の「Desktop Graphics - Reduced Memory Footprint」辺りにコレについての記述がある。

dicson 2011/04/12(火) 13:05:16
gakさん、ありがとうございます。
ではWPFはどこに描画しているのでしょうか?

gak 2011/04/12(火) 13:46:15
> ではWPFはどこに描画しているのでしょうか?
先に挙げたサイトに
> We achieved the reduction in system memory by accelerating the common GDI
> operations through the graphics hardware
とある。
「Vista では一度GDIアクセラレーションを全て捨て去ったので(GDIの為に)システムメ
モリ上にイメージを持たざるを得なかったけど、win7 では(重そうな処理に関する)GDI
アクセラレーションを復活(http://d.hatena.ne.jp/NyaRuRu/20090208/p1)させたので
わざわざシステムメモリ上にイメージを持たなくても何とかなった」
と俺は解釈したので、(GDIで無い)WPFはvista以前から直で VRAM に描いてたんじゃ
ね?多分。

# WPFはあんま触った事ないんだわ…

gak 2011/04/12(火) 13:53:24
> (GDIの為に)システムメモリ上にイメージを…
(GDIのソフトウェアレンダリングの為に)システムメモリ上にイメージを…

に修正。

gak 2011/04/12(火) 13:58:29
> (重そうな処理に関する)GDIアクセラレーションを復活
重いかどうかよりも「使用頻度高いGDIアクセラレーション」だろうな。多分。
何かぐだぐだだ。

dicson 2011/04/12(火) 14:08:51
gakさん、ありがとうございます。
では、自ウィンドウのVRAMアドレスはどこですか?または、調べる関数はありますか?

gak 2011/04/12(火) 14:25:49
> では、自ウィンドウのVRAMアドレスはどこですか?
それは DWM(Desktop Window Manager) の管轄内で、自ウィンドウの管轄外じゃないか
な。基本関与できないんじゃね?

> または、調べる関数はありますか?
http://msdn.microsoft.com/en-us/library/aa969527.aspx
DWM の api で提供されてなきゃ難しいんじゃないかと。俺は↑をきちんと見てないんで、
求める機能が提供されていないか調べてみたら良いかと。

dicson 2011/04/12(火) 16:31:44
DWMAPIに隠しAPIがあるようです。
NONAMEなのですが、パスはどうやって取得しますか?

gak 2011/04/12(火) 18:20:24
> DWMAPIに隠しAPI
DwmpDxGetWindowSharedSurface() の事?

> NONAMEなのですが、パスはどうやって取得しますか?
NONAMEなので GetProcAddress() に関数名指定できない、って意味?
関数名が判らないなら順序数(http://www.geoffchappell.com/viewer.htm?doc=studies
/windows/win32/dwmapi/api/index.htm)を指定してやれば良いかと。

http://winjade.net/board/index.php?showtopic=6286&st=0&p=85115&#entry85115
これが参考になるんじゃね。実際に俺が試したわけではないんで断言はできないけど。

後、上記サイトでは「このコードじゃ真っ黒なテクスチャしか取れない!」ってなってる
けど、これは DirectX3D9Ex ではなく DirectX3D9 で処理を進めているため、という可能
性もありえる。Aero は DirectX3D9Ex 専用らしい(http://d.hatena.ne.jp/NyaRuRu
/20061017/p3)ので、リソースを共有するなら DirectX3D9Ex でやらなきゃダメだし。
実際にテストしたわけじゃないんでこの視方が合ってるかどうかは知らんけどね。

# 隠しAPIに手を出すレベルとなると、俺の知識ではこの程度のレスが限界…

dicson 2011/04/12(火) 21:18:54
ありがとうございます。
DwmpDxGetWindowSharedSurface() の事ですが、
取得したハンドルの使い方を教えてください。

そのハンドルを何関数に渡せば良いのでしょうか?

gak 2011/04/13(水) 10:07:21
> DwmpDxGetWindowSharedSurface() の事ですが、
> 取得したハンドルの使い方を教えてください。
関数名や先に俺が挙げたサイト等の情報からすると↓が得られてると妄想可。
http://msdn.microsoft.com/en-us/library/bb219800.aspx#Sharing_Resources
# 非公開関数でドキュメントが公開されて無いんだから妄想するしかねー

で、こっから先に行きたければ DirectX3D の知識が必要。適当な解説サイトを見つける
等して地道に理解していくしかないかと。

gak 2011/04/13(水) 10:13:42
今更かもしんないけど、dicsonさんがやりたい最終目的を改めて明示した方が良いと思う。
メモリのアドレスを知る事や非公開APIの使い方を知る事が最終目的では無いよね。多分。

最終目的を明示する事によってもっと手軽にその目的を達する別解が提示される事がある
かもしれない。

dicson 2011/04/13(水) 10:42:38
WPFみたいな描画をSDKで行いたいと考えています。
WPFはDirectXでDWM用のデータ(0xAARRGGBB)を吐くそうです。
GDIを用いない描画システムを考えています。

PATIO 2011/04/13(水) 12:01:46
一つ言える事は非公開関数に関しては内部の事情で勝手に
仕様が変えられても文句は言え無いので趣味の範疇で使うなら
良いかもしれないけれど、外部に公開するような物に使うのなら
やめた方がいいのではと言う話です。
単純に技術的な興味とか研究的な意味合いなら止めません。

既に書かれているように非公開関数を使うのだったら
トライアンドエラーでやるしかないんじゃないかなぁ。
ある程度は検討がついたとしてもそれが正しいと言う裏付けが
取れませんからねぇ。動いているから多分正しいんだろうとか
そんな話ですよね。

ryo 2011/04/13(水) 12:30:36
>WPFみたいな描画をSDKで行いたいと考えています。
>WPFはDirectXでDWM用のデータ(0xAARRGGBB)を吐くそうです。
>GDIを用いない描画システムを考えています。

DirectXを使えばいいのでは・・・

dicson 2011/04/13(水) 13:42:25
PATIOさん、たしかにそうですが研究中ですので。。
ryoさん、DirectXはちょっと使いにくいので・・

subaru 2011/04/13(水) 18:03:38
>WPFみたいな描画をSDKで行いたいと考えています。
Win32からはWIC(Windows Imaging Component)、Direct2D、DirectWriteを使うべき。
ちなみにDirectXをインストールしなくてもSDKのみで使えますよ。

dicson 2011/04/14(木) 17:38:22
subaruさん、ありがとうございます。Windows Imaging Componentとは何ですか?
dllダウンロードと.NETの話しか出てこないのですが・・

YuO [E-Mail] 2011/04/14(木) 18:10:26
調べてみました。

MSDNのヘルプが以下になります。
MSDN: Windows Imaging Component (Windows)
http://msdn.microsoft.com/en-us/library/ee719902.aspx


あと,MSDNマガジンで2記事ほどありました。
MSDN: Windows with C++: Windows Imaging Component Basics
http://msdn.microsoft.com/ja-jp/magazine/cc500647.aspx
MSDN: Windows と C++: WIC を使用した Windows Vista アイコンのデコード
http://msdn.microsoft.com/ja-jp/magazine/cc546571.aspx

ITO 2011/04/14(木) 21:00:15
ROMしてたんですが.....
dicsonさん、
 VRAMを直接制御できたのは、NECのPC-9801XXの全盛期のころですね。
グラフィック用のICもμPD7220系列で上位互換がありました。
DOS/Vも直接制御できたかもしれませんが、グラフィック用のICが機種ごとに
違ったのでややこしかったかも知れませんね。
統一規格はあったのですが.......
現在にいたっては、GPUのメーカも競争、かつ、VRAMの制御も独自規格です。
VRAMの直接制御は無理ですね。
 WPFはぐぐれば専用のページが見れます。
ただ要約すると、
  「vistaの頃のプレゼンテーションの機能をWindows7で実現する。」
みたいで、
  GDI、DirectX等を使わないで直接VRAMを制御して高速に描画する。
のではないと思います。
vistaのグラフィックの描画はかえって遅かったのではないでしょうか。

むしろ、GDIやDirectX等を使って描画のアルゴリズムを考えるほうがいいと思います。

subaru 2011/04/15(金) 11:31:11
おおざっぱに説明するとWICがGDI+のBitmapクラスの機能に相当するもので
Direct2DがGDI+のGraphicsクラスの機能に相当すると言えるでしょうか。
WICはWPFでも使われていて、元々Vista以降からサポートされていましたが
現在はXPのSP3でも標準で使えるようになっていたと思います。

WPFの描画には、WPFとDirect3Dの中間にMedia Integration Layer(MIL)と
呼ばれるものが関わっているそうですが、VC++から直接MILを使うことは
できないようです。
(MSDNにはIMILBitmapEffectというインターフェースの説明もあるけど
本当に存在するか怪しい?)
しかしネイティブでもDirect3DをベースにDirect2Dが作られ
MILより高パフォーマンスな描画ができるようになった
・・・という話がこの辺りに書かれています。
http://msdn.microsoft.com/ja-jp/magazine/dd861344.aspx

Direct2DとDirectWriteはWindows7から提供されましたが
現在はVista SP2以降でも利用できるようになっているようで、
IE9やFireFox4でも採用されています。

YuO [E-Mail] 2011/04/15(金) 11:50:12
> ただ要約すると、
>   「vistaの頃のプレゼンテーションの機能をWindows7で実現する。」
> みたいで、

これはWPFのことを言っていますか?
WPFはそういうものではないですよ。
そもそもWPFの描画はDirectX9に依る様になっていて,だからこそWindows XPでもWPFが動
くのですが。
# XPだといろいろ残念な描画になることも多いですが……。

> vistaのグラフィックの描画はかえって遅かったのではないでしょうか。

CPUがそれなりに速ければ遅いことはないですけどね。
ベンチマークはともかく。

個人的にNyaruru氏は信用できると思っているし,
否定するだけの知識を持っていないのでNyaruru氏のはてなダイアリーからいくつか参考
記事を挙げますが,
これらを読むかぎり,Windows 7で高速化,ということは無いように思えます。

Site: Windows Vista での GDI/GDI+ 描画 - NyaRuRuの日記
http://d.hatena.ne.jp/NyaRuRu/20061201/p1
Site: WDDM, DWM: pros and cons - NyaRuRuの日記
http://d.hatena.ne.jp/NyaRuRu/20061202/p2
Site: Windows 7 のグラフィックスの変更点を整理する - NyaRuRuの日記
http://d.hatena.ne.jp/NyaRuRu/20081126/p1
Site: GDI アクセラレーションについて整理する - NyaRuRuの日記
http://d.hatena.ne.jp/NyaRuRu/20090208/p1

ITO 2011/04/15(金) 13:53:03
> これはWPFのことを言っていますか?
> WPFはそういうものではないですよ。
うーーん、
そうですか、失礼しました。
まぁー僕が言いたかったのは、
 dicsonさんが求めているのはVRAMに直接描画するような高速な方法はないですか?
ということだと思ったのですが、違いましたか?
ぼくはただ、「WPFでもおそらく無理です。」ということを説明したかっただけですね。
それでも、WPFに興味があって使ってみたいのであれば、WPFでぐぐればMSDNのページが
検索できます。

dicson 2011/04/15(金) 15:14:37
[[解決]]
みなさんありがとうございました。

とりあえずVRAM直接描画は無理で、Direct2D,Write,3Dを使うべきだということがわかり
ました。
WICとDirect2Dでやってみようと思います。

古いスレッドには追加発言できません。