Visual StudioによるOBSのプラグイン開発手順
はじめに
Visual StuioでOBSのプラグインを開発する準備について説明します。 詳細な手順がネットで見つからなかったので、独自に手順を検討しました。 デバッガで効率的にプラグインをデバッグできるようにします。
手順
OBS Studioをビルドする。(以下、ビルドディレクトリは C:\projects\obs-build
として説明)
OBS Studioのビルド手順の詳細についてはこちらを参照。
プラグインのテンプレートをローカルにcloneする。
注:詳細はまだ研究できていないが、github上で動くCIがこのテンプレートで実装されており、マルチプラットフォーム開発に便利なテンプレートになっている。
$ cd [PLUGIN DIR] $ cmake -S . -B build -Dlibobs_DIR="/c/projects/obs-build/libobs" -Dw32-pthreads_DIR="/c/projects/obs-build/deps/w32-pthreads"
生成された [PLUGIN DIR]/build/obs-plugintemplate.sln
をVisual Stuioで開く。
obs-plugintemplate
プロジェクト > Properties > Configuration Properties > Debugging にて
- Commandに
C:\projects\obs-build\rundir\Debug\bin\64bit\obs64.exe
- Working Directoryに
C:\projects\obs-build\rundir\Debug\bin\64bit
を設定する。
また obs-plugintemplate
プロジェクト > Properties > Configuration Properties > Build Events > Post-Build Event にて
- Command Lineに
copy C:\projects\<PLUGIN DIR>\build\rundir\Debug\obs-plugins\64bit\* C:\projects\obs-build\rundir\Debug\obs-plugins\64bit
を既存のコマンドの最後に追記し、OBS本体にデプロイされるようにする。
注: ここまで説明したように、手動でプロジェクトに設定変更を加える方法では、CMakeでプロジェクトを生成し直す度に再設定が必要になる。 CMakeのスクリプトに以下のような修正を加えておくことで、手動での設定が不要になる。
注:別の方法として、プロセスにアタッチする方法もあるが、この方法の欠点は bool obs_module_load(void)
の実行段階のデバッグができないこと。OBSにアタッチするタイミングではすでにプラグインのロードが完了してしまっているため。
obs-plugintemplate
プロジェクトをビルドする。
Visual Studioにてソースコードにブレイクポイントを設定する。
Visual StudioにてLocal Windows Debugger を実行する。
するとOBSが起動し、ブレイクポイントで実行が停止する。
OBS Code Reading: ウインドウタイトルのバージョン情報の仕様
はじめに
これは、OBSのウインドウのタイトルがどのように決められているのか突き止めるまでのメモです。
今回使用したバージョンはこちらです。
https://github.com/obsproject/obs-studio/tree/e8dc70d0eef4503378d6ac300e680215eb5c9379
結論
開発版のOBSは、ビルド対象のOBSの作業ツリーで
git describe --always --tags --dirty=-modified
を実行した結果がウインドウのタイトルとして使用される。
このコマンドを実行すると、具体的には、このような結果が得られる。
$ git describe --always --tags --dirty=-modified 28.0.0-8-gbfa2053b0-modified
読み方は
つまり、タイトルを見れば、ビルドされたOBSのバージョンを正確に知ることができる。
調査
OBS 28.0.0がリリースされた時付近に、このバージョン番号変更のコミットがあるのを覚えていました。 github.com
/* * Increment if major breaking API changes */ #define LIBOBS_API_MAJOR_VER 28
LIBOBS_API_MAJOR_VER
の値がタイトルに使われているのでは?という予想の元、LIBOBS_API_MAJOR_VER
で検索してみます。
そうすると、以下の関数が見つかりました。コードの内容的に、ここでウインドウタイトルのバージョン情報が作られているのは確実です。
string OBSApp::GetVersionString() const { stringstream ver; #ifdef HAVE_OBSCONFIG_H ver << OBS_VERSION; #else ver << LIBOBS_API_MAJOR_VER << "." << LIBOBS_API_MINOR_VER << "." << LIBOBS_API_PATCH_VER; #endif ver << " ("; #ifdef _WIN32 if (sizeof(void *) == 8) ver << "64-bit, "; else ver << "32-bit, "; ver << "windows)"; #elif __APPLE__ ver << "mac)"; #elif __OpenBSD__ ver << "openbsd)"; #elif __FreeBSD__ ver << "freebsd)"; #else /* assume linux for the time being */ ver << "linux)"; #endif return ver.str(); }
Visual Studio上では HAVE_OBSCONFIG_H
の分岐が有効になっています。
つまり、開発中は先ほど検索したLIBOBS_API_MAJOR_VER
は参照されません。
OBS_VERSION
で検索します。
すると、以下のcmake/Modules/VersionConfig.cmake
で値が決定されていることが分かりました。
# Set full and canonical OBS version from current git tag or manual override if(NOT DEFINED OBS_VERSION_OVERRIDE) if(NOT DEFINED RELEASE_CANDIDATE AND NOT DEFINED BETA AND EXISTS "${CMAKE_SOURCE_DIR}/.git") execute_process( COMMAND git describe --always --tags --dirty=-modified OUTPUT_VARIABLE _OBS_VERSION WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE _OBS_VERSION_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE) if(_OBS_VERSION_RESULT EQUAL 0) if(${_OBS_VERSION} MATCHES "rc[0-9]+$") set(RELEASE_CANDIDATE ${_OBS_VERSION}) elseif(${_OBS_VERSION} MATCHES "beta[0-9]+$") set(BETA ${_OBS_VERSION}) else() string(REPLACE "-" "." _CANONICAL_SPLIT ${_OBS_VERSION}) string(REPLACE "." ";" _CANONICAL_SPLIT ${_CANONICAL_SPLIT}) list(GET _CANONICAL_SPLIT 0 1 2 _OBS_VERSION_CANONICAL) string(REPLACE "." ";" _OBS_VERSION ${_OBS_VERSION}) endif() endif() endif()
git describe --always --tags --dirty=-modified
の値が使われているようです。
実際に実行してみると
$ git describe --always --tags --dirty=-modified 28.0.0-8-gbfa2053b0-modified
のような結果が得られました。ウインドウのタイトルのバージョン情報と一致しています。
このコマンドは、以下のように解釈できます。
以下の libobs/obsconfig.h.in
をテンプレートとして入力し、バージョン情報を置換してobsconfig.h
を生成します。
#pragma once #ifndef ON #define ON 1 #endif #ifndef OFF #define OFF 0 #endif #define OBS_VERSION "@OBS_VERSION@" #define OBS_VERSION_CANONICAL "@OBS_VERSION_CANONICAL@" #define OBS_DATA_PATH "@OBS_DATA_PATH@" #define OBS_INSTALL_PREFIX "@OBS_INSTALL_PREFIX@" #define OBS_PLUGIN_DESTINATION "@OBS_PLUGIN_DESTINATION@" #define OBS_QT_VERSION @_QT_VERSION@ [...]
さらにビルドディレクトリまで検索範囲を広げると、生成されたobsconfig.h
が見つかりました。
$ cd obs-build $ grep -rn OBS_VERSION . [...] ./config/obsconfig.h:12:#define OBS_VERSION "28.0.0-8-gbfa2053b0-modified" [...]
これで、ウインドウのタイトルが決められるまでの過程を追うことができました。
Visual Studio Community 2022でOBSをビルドする手順
はじめに
これはVisual Studio Community 2022でOBSをビルドする手順の記録です。 64bitのWindows版のOBSをビルドします。
基本的にこの手順に従います。
Wiki - Build Instructions For Windows | OBS
必要なソフト
- Visual Studio Community 2022
- Windows 10 SDK https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
- Pre-built Windows dependencies →C:/projects/obs-deps以下にzipファイルを展開しておく
- CMake
- git
手順
コードをクローンする。
% mkdir ~/projects % cd ~projects/ % git clone --recursive https://github.com/obsproject/obs-studio.git
CMakeでの作業
CMake(GUI)を起動する。
以下を設定する。
Where is the source code →C:/projects/obs-studio
Where to build the binaries →C:/projects/obs-build
最低限、以下のエントリーを追加する。
CMAKE_PREFIX_PATH 例: C:/projects/obs-deps/windows-deps-2022-08-02-x64
QTDIR 例: C:/projects/obs-deps/windows-deps-qt6-2022-08-02-x64
Configureを実行する。 コンパイラの指定が求められるので「Visual Studio 17 2022」を選択する。
Generateを実行する。
コマンドでのプロジェクト生成
CMakeの使い方に慣れてきたら、コマンド版のCMakeを利用するとより便利になる。 以下のコマンドで上記と同様のプロジェクトを生成できる。
$ cd /c/projects/obs-studio $ cmake -S . -B ../obs-build -DCMAKE_PREFIX_PATH="/c/projects/obs-deps/windows-deps-2022-08-02-x64" -DQTDIR="/c/projects/obs-deps/windows-deps-qt6-2022-08-02-x64"
Visual Studioでの作業
生成が成功したら、C:\projects\obs-build\obs-studio.slnを開く
ソリューションをビルドする。
ビルドが成功したら、C:\projects\obs-build\rundir\Debug\bin\64bit以下にobs64.exeが生成される。
任意の場所にブレークポイントをセットすることで、Visual Studioでのデバッグも可能。
注意事項
ビルドに関する問題の対処について記します。
キャッシュ問題
別のブランチに変更した場合、キャッシュが残って、リビルドしても前の状態が残ってしまう場合がある。 対処としては、2パターン考えられる。
- ソフトリセット:CMakeによるプロジェクト生成を再実行する (
git pull
で軽微な変更を適用する場合) - ハードリセット:ビルドディレクトリ(C:/projects/obs-build)を丸ごと削除し、CMakeによるプロジェクト生成を再実行する。
warning C4819エラーの対処
CP932環境として設定されたWindowsでビルドすると、以下のエラーが出てビルドできない場合がある。
17>C:\projects\obs-studio\plugins\obs-ffmpeg\external/nvEncodeAPI.h(1291,1): error C2220: 次の警告はエラーとして処理されます (ソース ファイルをコンパイルしています C:\projects\obs-studio\plugins\obs-ffmpeg\jim-nvenc-helpers.c)
以下の記事を参考に、システムの設定を変更することで、このエラーを回避できる。
XcodeでOBSをビルドとデバッグするまで
はじめに
今回はXcodeでOBSをビルドし、デバッグできるようにするまでの手順を記録します。 色々うまくいかなかったですが、試行錯誤してデバッグできる状態まで持っていけました。
手順
基本的にここのマニュアルの通りでOK。
Build Instructions For Mac · obsproject/obs-studio Wiki · GitHub
Xcodeを削除してしまっていたので、再インストールした。 AppStoreからだと異様に遅く、進捗が見えないので、ここからXcodeをダウンロードしてインストールした。 https://developer.apple.com/download/all/
Swigがうまく認識しなかったので、-DSWIG_DIR
でobs-deps配下のSwigを使用するように指定。
% cmake -S . -B build -G Xcode \ -DCEF_ROOT_DIR="~/development/obs-build-dependencies/cef_binary_4638_macos_x86_64" \ -DCMAKE_PREFIX_PATH="~/development/obs-build-dependencies/obs-deps" \ -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ -DCMAKE_OSX_ARCHITECTURES="x86_64" -DSWIG_DIR="/Users/yoshinori_sano/development/obs-build-dependencies/obs-deps/share/swig/4.1.0"
cmakeでエラー
cmakeを実行すると以下のようにコンパイラが見つからないエラーが発生した。
% cmake -S . -B build -G Xcode \ -DCEF_ROOT_DIR="~/development/obs-build-dependencies/cef_binary_4638_macos_x86_64" \ -DCMAKE_PREFIX_PATH="~/development/obs-build-dependencies/obs-deps" \ -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ -DCMAKE_OSX_ARCHITECTURES="x86_64" -DSWIG_DIR="/Users/yoshinori_sano/development/obs-build-dependencies/obs-deps/share/swig/4.1.0" -- OBS: Application Version: 28.0.0-beta1-8-g76e9c64f4 - Build Number: 63 -- The C compiler identification is unknown -- The CXX compiler identification is unknown CMake Error at CMakeLists.txt:15 (project): No CMAKE_C_COMPILER could be found. CMake Error at CMakeLists.txt:15 (project): No CMAKE_CXX_COMPILER could be found.
エラーログを確認すると、以下のエラーがあった。
% less ~/projects/obs-studio/build/CMakeFiles/CMakeError.log [...] xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
調べたら、XcodeのPreferenceの設定をすれば良いことが分かった。
Xcodeを再インストールした時に、状態がおかしくなったのかもしれない。
Preference > Locations > Command Line Toolsが空の状態になっていたので、Xcode 13.4.1を選択。
ビルドと実行
以下のコマンドを実行したら、buildディレクトリ配下に「obs-studio.xcodeproj」が生成されるのでXcodeで開く。
% cmake -S . -B build -G Xcode \ -DCEF_ROOT_DIR="~/development/obs-build-dependencies/cef_binary_4638_macos_x86_64" \ -DCMAKE_PREFIX_PATH="~/development/obs-build-dependencies/obs-deps" \ -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ -DCMAKE_OSX_ARCHITECTURES="x86_64" -DSWIG_DIR="/Users/yoshinori_sano/development/obs-build-dependencies/obs-deps/share/swig/4.1.0"
Schemaをobsに変更してビルドを実行する。しばらくすると、OBSが起動する。
デバッグできない問題
ブレークポイントを追加しても、無効になってしまう問題が発生。
OBSのDiscordで質問してみたものの、よく分からず。
デバッグシンボルが付いてないのかなと思ってcmakeからやり直してみることに。
解決方法
Xcodeのプロジェクトファイルを生成する時に、-DCMAKE_BUILD_TYPE=Debug
をcmakeのオプションに追加することでデバッグ版のOBSが生成されるようになる。
% cmake -S . -B build -G Xcode \ -DCEF_ROOT_DIR="~/development/obs-build-dependencies/cef_binary_4638_macos_x86_64" \ -DCMAKE_PREFIX_PATH="~/development/obs-build-dependencies/obs-deps" \ -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \ -DCMAKE_OSX_ARCHITECTURES="x86_64" -DSWIG_DIR="/Users/yoshinori_sano/development/obs-build-dependencies/obs-deps/share/swig/4.1.0" -DCMAKE_BUILD_TYPE=Debug
Blink: Shadow DOMのLayoutTestを実行する
はじめに
BlinkでShadow DOMのLayoutTestを実行する手順のメモです。
仕様
今回は以下の仕様のLayoutTestをピンポイントで実行します。
http://www.w3.org/TR/shadow-dom/
Invoking the cloneNode() method on a ShadowRoot instance must always throw a DATA_CLONE_ERR exception.
テストコード
以下のようなテストコードが用意されています。Shadow Rootに対してcloneNode()すると25番のExceptionが投げられるという単純なテストです。25番は仕様のDATA_CLONE_ERRに対応していて、core/dom/ExceptionCode.hで25と定義されています。
LayoutTest/fast/dom/shadow/shadowroot-clonenode.html
<!DOCTYPE> <html> <script src="../../js/resources/js-test-pre.js"></script> <pre id="console"></pre> <script> description('Calling ShadowRoot.cloneNode() should throw a DATA_CLONE_ERR exception.'); var host = document.createElement('div'); var shadowRoot = host.webkitCreateShadowRoot(); shouldThrow('shadowRoot.cloneNode()', '"Error: DataCloneError: DOM Exception 25"'); </script> <script src="../../js/resources/js-test-post.js"></script> </html>
core/dom/ExceptionCode.h
// Others introduced in HTML5: NETWORK_ERR = 19, ABORT_ERR = 20, URL_MISMATCH_ERR = 21, QUOTA_EXCEEDED_ERR = 22, TIMEOUT_ERR = 23, INVALID_NODE_TYPE_ERR = 24, DATA_CLONE_ERR = 25,
LayoutTestの実行
LayoutTestを実行しています。成功します。
> cd src\webkit\tools\layout_tests > python.exe run_webkit_tests.py --nocheck-sys-deps --debug fast\dom\shadow\shadowroot-clonenode.html Using port 'chromium-win-win7' Test configuration: <win7, x86, debug> Placing test results in F:\ssdcygwin\home\fixme\chrome\src\webkit\Debug\layout-t est-results Baseline search path: chromium-win -> generic Using Debug build Pixel tests enabled Regular timeout: 12000, slow test timeout: 60000 Command line: F:\ssdcygwin\home\fixme\chrome\src\build\Debug\DumpRenderTree.exe - Found 0 tests; running 0, skipping 0. No tests to run.
失敗させてみる
shadowroot-clonenode.htmlを適当にいじって、再度実行すると、失敗しました。
> python.exe run_webkit_tests.py --nocheck-sys-deps --debug fast\dom\shadow\shadowroot-conenode.html Using port 'chromium-win-win7' Test configuration: <win7, x86, debug> Placing test results in F:\ssdcygwin\home\fixme\chrome\src\webkit\Debug\layout- est-results Baseline search path: chromium-win -> generic Using Debug build Pixel tests enabled Regular timeout: 12000, slow test timeout: 60000 Command line: F:\ssdcygwin\home\fixme\chrome\src\build\Debug\DumpRenderTree.exe - Found 1 test; running 1, skipping 0. Ruby is not installed; can't generate pretty patches. Running 1 DumpRenderTree. [1/1] fast/dom/shadow/shadowroot-clonenode.html failed unexpectedly (text diff) 0 tests ran as expected, 1 didn't: Regressions: Unexpected text-only failures (1) fast/dom/shadow/shadowroot-clonenode.html [ Failure ]
Chromium Code Reading: Experimentalな機能の実装(WebPのAcceptヘッダ送出)
はじめに
Google+を見ていたら、面白そうなポストがありました。
https://plus.google.com/100132233764003563318/posts/KRU6nxp7LXG
Canaryビルドに新しいExperimentalな機能が追加されました。簡単に言うと、画像のリクエスト時にHTTPリクエストのAcceptヘッダにWebP画像をサポートしていることをWebサーバに伝える仕組みです。
今回Canaryに追加されたこの機能は、差分量も小さく、Experimentalな機能の追加方法を学ぶのに最適と思いました。
以下が対象のコードです。
- Issue 14273007: Add a switch to Chromium to enable/disable 'image/webp' accept header.
https://codereview.chromium.org/14273007/
- Issue 13814024: Add a runtime flag in WebRuntimeFeatures to enable 'image/webp' accept header
chrome://flags
ChromeのURLバーから chrome://flags にアクセスすると、Experimentalな機能のON/OFFができます(以下、スイッチと呼びます)。
最新のChromiumでは以下のような画面が表示されます。
スイッチの定義
chrome://flags で表示されるスイッチの説明文はgenerated_resources.grdに定義されています。
src/chrome/app/generated_resources.grd
<message name="IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_NAME" desc="Title for the flag to enable 'image/webp' in accept header."> Enable 'image/webp' accept header </message> <message name="IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_DESCRIPTION" desc="Description for the flag to enable 'image/webp' in accept header."> Enables 'image/webp' accept header in HTTP requests for images, to denote WebP image support. </message>
スイッチの特徴がkExperiments定数内に定義されます。
スイッチの説明文、対応OS、スイッチの種類(SINGLE_VALUEはON/OFFのみのスイッチ)など。
const Experiment kExperiments[] = { [...] { "enable-webp-in-accept-header", IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_NAME, IDS_FLAGS_ENABLE_WEBP_IN_ACCEPT_HEADER_DESCRIPTION, kOsAll, SINGLE_VALUE_TYPE(switches::kEnableWebPInAcceptHeader) }, };
初期化
スイッチのデフォルト値はfalseになっていました。
bool RuntimeEnabledFeatures::isWebPInAcceptHeaderEnabled = false;
Blinkの初期化時に、chrome://flagsで設定されたスイッチの状態取得とランタイム機能郡(WebRuntimeFeatures)にスイッチ状態をセットします。
void RenderThreadImpl::EnsureWebKitInitialized() { [...] WebRuntimeFeatures::enableWebPInAcceptHeader( command_line.HasSwitch(switches::kEnableWebPInAcceptHeader)); [...] }
WebRuntimeFeaturesからRuntimeEnabledFeaturesに委譲されています。
void WebRuntimeFeatures::enableWebPInAcceptHeader(bool enable) { RuntimeEnabledFeatures::setWebPInAcceptHeaderEnabled(enable); }
class RuntimeEnabledFeatures { [...] static void setWebPInAcceptHeaderEnabled(bool isEnabled) { isWebPInAcceptHeaderEnabled = isEnabled; } static bool webPInAcceptHeaderEnabled() { return isWebPInAcceptHeaderEnabled; }
スイッチの利用
ここからは、Experimentalな機能の実装に依存するコードです。
void CachedImage::setCustomAcceptHeader() { if (RuntimeEnabledFeatures::webPInAcceptHeaderEnabled()) setAccept("image/webp,*/*;q=0.8"); }
余談: バックトレース
バックトレースの取得にcontent shellを使います。content shellとはレンダリングエンジン(Blink)の動作確認に使える軽量ブラウザです。
こんな画面です。質素です。
CachedImage::setCustomAcceptHeaderにブレークポイントを設定して、バックトレースを取ってみます。
と、その前に、content_shellプロジェクトのプロパティからコマンドライン引数に「--single-process」オプションを設定しておきます。
これをしておかないとうまくバックトレースが取れません。
バックトレースをざっくり読み解くと、HTMLのパース(最近HTMLのパースはBackgroundParserでスレッド化された!)、CSSのスタイル解決、画像のロード、キャッシュイメージの生成、を経たことがわかります。
誰が画像を要求したのか、解明してみます。
スタックとレースからStyleResolver::loadPendingImagesを見てみると、CSSのbackground-imageのURLに指定された画像を取得しようとしているようです。
どんな画像?
StyleResolver::loadPendingImageのローカル変数imageValueのm_urlをデバッガで見ると、http://www.google.co.jp/images/srpr/logo4w.png でした。
content shellを起動すると、http://www.google.co.jp/に行くので、Googleトップページのロゴ画像と言うわけです。
> webkit.dll!WebCore::CachedImage::setCustomAcceptHeader() 行 301 C++ webkit.dll!WebCore::CachedImage::CachedImage(const WebCore::ResourceRequest & resourceRequest) 行 62 C++ webkit.dll!WebCore::createResource(WebCore::CachedResource::Type type, WebCore::ResourceRequest & request, const WTF::String & charset) 行 73 + 0x29 バイト C++ webkit.dll!WebCore::CachedResourceLoader::loadResource(WebCore::CachedResource::Type type, WebCore::CachedResourceRequest & request, const WTF::String & charset) 行 478 + 0x16 バイト C++ webkit.dll!WebCore::CachedResourceLoader::requestResource(WebCore::CachedResource::Type type, WebCore::CachedResourceRequest & request) 行 405 + 0x20 バイト C++ webkit.dll!WebCore::CachedResourceLoader::requestImage(WebCore::CachedResourceRequest & request) 行 155 + 0x12 バイト C++ webkit.dll!WebCore::CSSImageValue::cachedImage(WebCore::CachedResourceLoader * loader) 行 79 + 0x16 バイト C++ webkit.dll!WebCore::StyleResolver::loadPendingImage(WebCore::StylePendingImage * pendingImage) 行 4248 + 0xc バイト C++ webkit.dll!WebCore::StyleResolver::loadPendingImages() 行 4285 + 0x1b バイト C++ webkit.dll!WebCore::StyleResolver::loadPendingResources() 行 4360 C++ webkit.dll!WebCore::StyleResolver::applyMatchedProperties(const WebCore::StyleResolver::MatchResult & matchResult, const WebCore::Element * element) 行 1915 C++ webkit.dll!WebCore::StyleResolver::styleForElement(WebCore::Element * element, WebCore::RenderStyle * defaultParent, WebCore::StyleSharingBehavior sharingBehavior, WebCore::RuleMatchingBehavior matchingBehavior, WebCore::RenderRegion * regionForStyling) 行 1010 C++ webkit.dll!WebCore::Element::styleForRenderer() 行 1372 + 0x26 バイト C++ webkit.dll!WebCore::NodeRenderingContext::createRendererForElementIfNeeded() 行 247 + 0xc バイト C++ webkit.dll!WebCore::Element::createRendererIfNeeded() 行 1263 + 0x24 バイト C++ webkit.dll!WebCore::Element::attach() 行 1274 C++ webkit.dll!WebCore::executeTask(WebCore::HTMLConstructionSiteTask & task) 行 100 + 0x20 バイト C++ webkit.dll!WebCore::HTMLConstructionSite::executeQueuedTasks() 行 143 + 0x12 バイト C++ webkit.dll!WebCore::HTMLTreeBuilder::constructTree(WebCore::AtomicHTMLToken * token) 行 379 C++ webkit.dll!WebCore::HTMLDocumentParser::constructTreeFromCompactHTMLToken(const WebCore::CompactHTMLToken & compactToken) 行 617 C++ webkit.dll!WebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> popChunk) 行 428 C++ webkit.dll!WebCore::HTMLDocumentParser::pumpPendingSpeculations() 行 485 C++ webkit.dll!WebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> chunk) 行 334 C++ webkit.dll!WTF::FunctionWrapper<void (__thiscall WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()(const WTF::WeakPtr<WebCore::HTMLDocumentParser> & c, WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk> p1) 行 254 + 0x24 バイト C++ webkit.dll!WTF::BoundFunctionImpl<WTF::FunctionWrapper<void (__thiscall WebCore::HTMLDocumentParser::*)(WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>,void __cdecl(WTF::WeakPtr<WebCore::HTMLDocumentParser>,WTF::PassOwnPtr<WebCore::HTMLDocumentParser::ParsedChunk>)>::operator()() 行 523 C++ webkit.dll!WTF::Function<void __cdecl(void)>::operator()() 行 704 + 0x1a バイト C++ webkit.dll!WTF::callFunctionObject(void * context) 行 62 C++ glue.dll!base::internal::RunnableAdapter<void (__cdecl*)(void *)>::Run(void * const & a1) 行 171 + 0x18 バイト C++ glue.dll!base::internal::InvokeHelper<0,void,base::internal::RunnableAdapter<void (__cdecl*)(void *)>,void __cdecl(void * const &)>::MakeItSo(base::internal::RunnableAdapter<void (__cdecl*)(void *)> runnable, void * const & a1) 行 872 C++ glue.dll!base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl*)(void *)>,void __cdecl(void *),void __cdecl(void *)>,void __cdecl(void *)>::Run(base::internal::BindStateBase * base) 行 1173 + 0x19 バイト C++ base.dll!base::Callback<void __cdecl(void)>::Run() 行 396 + 0xe バイト C++ base.dll!base::MessageLoop::RunTask(const base::PendingTask & pending_task) 行 476 C++ base.dll!base::MessageLoop::DeferOrRunPendingTask(const base::PendingTask & pending_task) 行 489 C++ base.dll!base::MessageLoop::DoWork() 行 669 + 0xc バイト C++ base.dll!base::MessagePumpForUI::DoRunLoop() 行 241 + 0x1d バイト C++ base.dll!base::MessagePumpWin::RunWithDispatcher(base::MessagePump::Delegate * delegate, base::MessagePumpDispatcher * dispatcher) 行 64 + 0xf バイト C++ base.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) 行 48 + 0x1c バイト C++ base.dll!base::MessageLoop::RunInternal() 行 431 + 0x29 バイト C++ base.dll!base::MessageLoop::RunHandler() 行 405 C++ base.dll!base::RunLoop::Run() 行 46 C++ base.dll!base::MessageLoop::Run() 行 312 C++ base.dll!base::Thread::Run(base::MessageLoop * message_loop) 行 153 C++ base.dll!base::Thread::ThreadMain() 行 197 + 0x16 バイト C++ base.dll!base::`anonymous namespace'::ThreadFunc(void * params) 行 57 + 0xe バイト C++ kernel32.dll!751c33aa()
void StyleResolver::loadPendingImages() { if (m_state.pendingImageProperties().isEmpty()) return; PendingImagePropertyMap::const_iterator::Keys end = m_state.pendingImageProperties().end().keys(); for (PendingImagePropertyMap::const_iterator::Keys it = m_state.pendingImageProperties().begin().keys(); it != end; ++it) { CSSPropertyID currentProperty = *it; switch (currentProperty) { case CSSPropertyBackgroundImage: { for (FillLayer* backgroundLayer = m_state.style()->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) { if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) backgroundLayer->setImage(loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image()))); } break; }
PassRefPtr<StyleImage> StyleResolver::loadPendingImage(StylePendingImage* pendingImage) { CachedResourceLoader* cachedResourceLoader = m_state.document()->cachedResourceLoader(); if (pendingImage->cssImageValue()) { CSSImageValue* imageValue = pendingImage->cssImageValue(); return imageValue->cachedImage(cachedResourceLoader); }
Chromeにはじめて取り込まれたパッチ
記念すべき第1号です。
https://chromium.googlesource.com/chromium/src/+/15fc083b4a23e23417a6bf71f38e2f7966908590
単なるtypoの修正ですが、LGTM(Looks Good To Me)をもらった時は嬉しかったです。
Botがビルドとテストを走らせる様子も体験してみると楽しかったです。
https://codereview.chromium.org/14145003/
https://chromium-status.appspot.com/cq/yoshinori.sano%40gmail.com/14145003/6001