Commit 82180e82 authored by Frank Barchard's avatar Frank Barchard

rgb24toyuv use 1 or 2 steps consistently.

R=bcornell@google.com, impjdi@google.com
BUG=libyuv:459

Review URL: https://webrtc-codereview.appspot.com/52149004.
parent ef8cb9b0
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1440 Version: 1441
License: BSD License: BSD
License File: LICENSE License File: LICENSE
......
...@@ -11,6 +11,6 @@ ...@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1440 #define LIBYUV_VERSION 1441
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
...@@ -817,22 +817,20 @@ int RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24, ...@@ -817,22 +817,20 @@ int RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24,
src_stride_rgb24 = -src_stride_rgb24; src_stride_rgb24 = -src_stride_rgb24;
} }
// Neon version does direct RGB24 to YUV.
#if defined(HAS_RGB24TOYROW_NEON) #if defined(HAS_RGB24TOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) { if (TestCpuFlag(kCpuHasNEON)) {
RGB24ToUVRow = RGB24ToUVRow_Any_NEON;
RGB24ToYRow = RGB24ToYRow_Any_NEON; RGB24ToYRow = RGB24ToYRow_Any_NEON;
if (IS_ALIGNED(width, 8)) { if (IS_ALIGNED(width, 8)) {
RGB24ToYRow = RGB24ToYRow_NEON; RGB24ToYRow = RGB24ToYRow_NEON;
}
}
#endif
#if defined(HAS_RGB24TOUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
RGB24ToUVRow = RGB24ToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
RGB24ToUVRow = RGB24ToUVRow_NEON; RGB24ToUVRow = RGB24ToUVRow_NEON;
} }
} }
#endif }
// Other platforms do intermediate conversion from RGB24 to ARGB.
#else
#if defined(HAS_RGB24TOARGBROW_SSSE3) #if defined(HAS_RGB24TOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) { if (TestCpuFlag(kCpuHasSSSE3)) {
RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3;
...@@ -861,7 +859,6 @@ int RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24, ...@@ -861,7 +859,6 @@ int RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24,
} }
} }
#endif #endif
#if !defined(HAS_RGB24TOYROW_NEON)
{ {
// Allocate 2 rows of ARGB. // Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31; const int kRowSize = (width * 4 + 31) & ~31;
...@@ -934,22 +931,20 @@ int RAWToI420(const uint8* src_raw, int src_stride_raw, ...@@ -934,22 +931,20 @@ int RAWToI420(const uint8* src_raw, int src_stride_raw,
src_stride_raw = -src_stride_raw; src_stride_raw = -src_stride_raw;
} }
// Neon version does direct RAW to YUV.
#if defined(HAS_RAWTOYROW_NEON) #if defined(HAS_RAWTOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) { if (TestCpuFlag(kCpuHasNEON)) {
RAWToUVRow = RAWToUVRow_Any_NEON;
RAWToYRow = RAWToYRow_Any_NEON; RAWToYRow = RAWToYRow_Any_NEON;
if (IS_ALIGNED(width, 8)) { if (IS_ALIGNED(width, 8)) {
RAWToYRow = RAWToYRow_NEON; RAWToYRow = RAWToYRow_NEON;
}
}
#endif
#if defined(HAS_RAWTOUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
RAWToUVRow = RAWToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
RAWToUVRow = RAWToUVRow_NEON; RAWToUVRow = RAWToUVRow_NEON;
} }
} }
#endif }
// Other platforms do intermediate conversion from RAW to ARGB.
#else
#if defined(HAS_RAWTOARGBROW_SSSE3) #if defined(HAS_RAWTOARGBROW_SSSE3)
if (TestCpuFlag(kCpuHasSSSE3)) { if (TestCpuFlag(kCpuHasSSSE3)) {
RAWToARGBRow = RAWToARGBRow_Any_SSSE3; RAWToARGBRow = RAWToARGBRow_Any_SSSE3;
...@@ -978,7 +973,6 @@ int RAWToI420(const uint8* src_raw, int src_stride_raw, ...@@ -978,7 +973,6 @@ int RAWToI420(const uint8* src_raw, int src_stride_raw,
} }
} }
#endif #endif
#if !defined(HAS_RAWTOYROW_NEON)
{ {
// Allocate 2 rows of ARGB. // Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31; const int kRowSize = (width * 4 + 31) & ~31;
...@@ -1051,18 +1045,20 @@ int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565, ...@@ -1051,18 +1045,20 @@ int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565,
src_stride_rgb565 = -src_stride_rgb565; src_stride_rgb565 = -src_stride_rgb565;
} }
// Neon version does direct RGB565 to YUV.
#if defined(HAS_RGB565TOYROW_NEON) #if defined(HAS_RGB565TOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) { if (TestCpuFlag(kCpuHasNEON)) {
RGB565ToUVRow = RGB565ToUVRow_Any_NEON;
RGB565ToYRow = RGB565ToYRow_Any_NEON; RGB565ToYRow = RGB565ToYRow_Any_NEON;
if (IS_ALIGNED(width, 8)) { if (IS_ALIGNED(width, 8)) {
RGB565ToYRow = RGB565ToYRow_NEON; RGB565ToYRow = RGB565ToYRow_NEON;
}
RGB565ToUVRow = RGB565ToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
RGB565ToUVRow = RGB565ToUVRow_NEON; RGB565ToUVRow = RGB565ToUVRow_NEON;
} }
} }
#endif }
// Other platforms do intermediate conversion from RGB565 to ARGB.
#else
#if defined(HAS_RGB565TOARGBROW_SSE2) #if defined(HAS_RGB565TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2)) {
RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2; RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2;
...@@ -1099,7 +1095,6 @@ int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565, ...@@ -1099,7 +1095,6 @@ int RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565,
} }
} }
#endif #endif
#if !defined(HAS_RGB565TOYROW_NEON)
{ {
// Allocate 2 rows of ARGB. // Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31; const int kRowSize = (width * 4 + 31) & ~31;
...@@ -1172,19 +1167,20 @@ int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, ...@@ -1172,19 +1167,20 @@ int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555,
src_stride_argb1555 = -src_stride_argb1555; src_stride_argb1555 = -src_stride_argb1555;
} }
// Neon version does direct ARGB1555 to YUV.
#if defined(HAS_ARGB1555TOYROW_NEON) #if defined(HAS_ARGB1555TOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) { if (TestCpuFlag(kCpuHasNEON)) {
ARGB1555ToUVRow = ARGB1555ToUVRow_Any_NEON;
ARGB1555ToYRow = ARGB1555ToYRow_Any_NEON; ARGB1555ToYRow = ARGB1555ToYRow_Any_NEON;
if (IS_ALIGNED(width, 8)) { if (IS_ALIGNED(width, 8)) {
ARGB1555ToYRow = ARGB1555ToYRow_NEON; ARGB1555ToYRow = ARGB1555ToYRow_NEON;
}
ARGB1555ToUVRow = ARGB1555ToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGB1555ToUVRow = ARGB1555ToUVRow_NEON; ARGB1555ToUVRow = ARGB1555ToUVRow_NEON;
} }
} }
#endif }
// Other platforms do intermediate conversion from ARGB1555 to ARGB.
#else
#if defined(HAS_ARGB1555TOARGBROW_SSE2) #if defined(HAS_ARGB1555TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2)) {
ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2; ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2;
...@@ -1221,12 +1217,12 @@ int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, ...@@ -1221,12 +1217,12 @@ int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555,
} }
} }
#endif #endif
#if !defined(HAS_ARGB1555TOYROW_NEON)
{ {
// Allocate 2 rows of ARGB. // Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31; const int kRowSize = (width * 4 + 31) & ~31;
align_buffer_64(row, kRowSize * 2); align_buffer_64(row, kRowSize * 2);
#endif #endif
for (y = 0; y < height - 1; y += 2) { for (y = 0; y < height - 1; y += 2) {
#if defined(HAS_ARGB1555TOYROW_NEON) #if defined(HAS_ARGB1555TOYROW_NEON)
ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width); ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width);
...@@ -1236,6 +1232,7 @@ int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, ...@@ -1236,6 +1232,7 @@ int ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555,
#else #else
ARGB1555ToARGBRow(src_argb1555, row, width); ARGB1555ToARGBRow(src_argb1555, row, width);
ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize, ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize,
width); width);
ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); ARGBToUVRow(row, kRowSize, dst_u, dst_v, width);
ARGBToYRow(row, dst_y, width); ARGBToYRow(row, dst_y, width);
...@@ -1295,19 +1292,20 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444, ...@@ -1295,19 +1292,20 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
src_stride_argb4444 = -src_stride_argb4444; src_stride_argb4444 = -src_stride_argb4444;
} }
// Neon version does direct ARGB4444 to YUV.
#if defined(HAS_ARGB4444TOYROW_NEON) #if defined(HAS_ARGB4444TOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) { if (TestCpuFlag(kCpuHasNEON)) {
ARGB4444ToUVRow = ARGB4444ToUVRow_Any_NEON;
ARGB4444ToYRow = ARGB4444ToYRow_Any_NEON; ARGB4444ToYRow = ARGB4444ToYRow_Any_NEON;
if (IS_ALIGNED(width, 8)) { if (IS_ALIGNED(width, 8)) {
ARGB4444ToYRow = ARGB4444ToYRow_NEON; ARGB4444ToYRow = ARGB4444ToYRow_NEON;
}
ARGB4444ToUVRow = ARGB4444ToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) { if (IS_ALIGNED(width, 16)) {
ARGB4444ToUVRow = ARGB4444ToUVRow_NEON; ARGB4444ToUVRow = ARGB4444ToUVRow_NEON;
} }
} }
#endif }
// Other platforms do intermediate conversion from ARGB4444 to ARGB.
#else
#if defined(HAS_ARGB4444TOARGBROW_SSE2) #if defined(HAS_ARGB4444TOARGBROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2)) {
ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2; ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2;
...@@ -1344,8 +1342,6 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444, ...@@ -1344,8 +1342,6 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
} }
} }
#endif #endif
#if !defined(HAS_ARGB4444TOYROW_NEON)
{ {
// Allocate 2 rows of ARGB. // Allocate 2 rows of ARGB.
const int kRowSize = (width * 4 + 31) & ~31; const int kRowSize = (width * 4 + 31) & ~31;
......
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
A simple wrapper for protoc.
- Adds includes in generated headers.
- Handles building with system protobuf as an option.
"""
import fnmatch
import optparse
import os.path
import shutil
import subprocess
import sys
import tempfile
PROTOC_INCLUDE_POINT = '// @@protoc_insertion_point(includes)\n'
def ModifyHeader(header_file, extra_header):
"""Adds |extra_header| to |header_file|. Returns 0 on success.
|extra_header| is the name of the header file to include.
|header_file| is a generated protobuf cpp header.
"""
include_point_found = False
header_contents = []
with open(header_file) as f:
for line in f:
header_contents.append(line)
if line == PROTOC_INCLUDE_POINT:
extra_header_msg = '#include "%s"\n' % extra_header
header_contents.append(extra_header_msg)
include_point_found = True;
if not include_point_found:
return 1
with open(header_file, 'wb') as f:
f.write(''.join(header_contents))
return 0
def ScanForBadFiles(scan_root):
"""Scan for bad file names, see http://crbug.com/386125 for details.
Returns True if any filenames are bad. Outputs errors to stderr.
|scan_root| is the path to the directory to be recursively scanned.
"""
badname = False
real_scan_root = os.path.realpath(scan_root)
for dirpath, dirnames, filenames in os.walk(real_scan_root):
matches = fnmatch.filter(filenames, '*-*.proto')
if len(matches) > 0:
if not badname:
badname = True
sys.stderr.write('proto files must not have hyphens in their names ('
'see http://crbug.com/386125 for more information):\n')
for filename in matches:
sys.stderr.write(' ' + os.path.join(real_scan_root,
dirpath, filename) + '\n')
return badname
def RewriteProtoFilesForSystemProtobuf(path):
wrapper_dir = tempfile.mkdtemp()
try:
for filename in os.listdir(path):
if not filename.endswith('.proto'):
continue
with open(os.path.join(path, filename), 'r') as src_file:
with open(os.path.join(wrapper_dir, filename), 'w') as dst_file:
for line in src_file:
# Remove lines that break build with system protobuf.
# We cannot optimize for lite runtime, because system lite runtime
# does not have a Chromium-specific hack to retain unknown fields.
# Similarly, it does not understand corresponding option to control
# the usage of that hack.
if 'LITE_RUNTIME' in line or 'retain_unknown_fields' in line:
continue
dst_file.write(line)
return wrapper_dir
except:
shutil.rmtree(wrapper_dir)
raise
def main(argv):
parser = optparse.OptionParser()
parser.add_option('--include', dest='extra_header',
help='The extra header to include. This must be specified '
'along with --protobuf.')
parser.add_option('--protobuf', dest='generated_header',
help='The c++ protobuf header to add the extra header to. '
'This must be specified along with --include.')
parser.add_option('--proto-in-dir',
help='The directory containing .proto files.')
parser.add_option('--proto-in-file', help='Input file to compile.')
parser.add_option('--use-system-protobuf', type=int, default=0,
help='Option to use system-installed protobuf '
'instead of bundled one.')
(options, args) = parser.parse_args(sys.argv)
if len(args) < 2:
return 1
if ScanForBadFiles(options.proto_in_dir):
return 1
proto_path = options.proto_in_dir
if options.use_system_protobuf == 1:
proto_path = RewriteProtoFilesForSystemProtobuf(proto_path)
try:
# Run what is hopefully protoc.
protoc_args = args[1:]
protoc_args += ['--proto_path=%s' % proto_path,
os.path.join(proto_path, options.proto_in_file)]
ret = subprocess.call(protoc_args)
if ret != 0:
return ret
finally:
if options.use_system_protobuf == 1:
# Remove temporary directory holding re-written files.
shutil.rmtree(proto_path)
# protoc succeeded, check to see if the generated cpp header needs editing.
if not options.extra_header or not options.generated_header:
return 0
return ModifyHeader(options.generated_header, options.extra_header)
if __name__ == '__main__':
sys.exit(main(sys.argv))
swarming_client @ b39a448d
Subproject commit b39a448d8522392389b28f6997126a6ab04bfe87
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Autocompletion config for YouCompleteMe in Chromium.
#
# USAGE:
#
# 1. Install YCM [https://github.com/Valloric/YouCompleteMe]
# (Googlers should check out [go/ycm])
#
# 2. Create a symbolic link to this file called .ycm_extra_conf.py in the
# directory above your Chromium checkout (i.e. next to your .gclient file).
#
# cd src
# ln -rs tools/vim/chromium.ycm_extra_conf.py ../.ycm_extra_conf.py
#
# 3. (optional) Whitelist the .ycm_extra_conf.py from step #2 by adding the
# following to your .vimrc:
#
# let g:ycm_extra_conf_globlist=['<path to .ycm_extra_conf.py>']
#
# You can also add other .ycm_extra_conf.py files you want to use to this
# list to prevent excessive prompting each time you visit a directory
# covered by a config file.
#
# 4. Profit
#
#
# Usage notes:
#
# * You must use ninja & clang to build Chromium.
#
# * You must have run gyp_chromium and built Chromium recently.
#
#
# Hacking notes:
#
# * The purpose of this script is to construct an accurate enough command line
# for YCM to pass to clang so it can build and extract the symbols.
#
# * Right now, we only pull the -I and -D flags. That seems to be sufficient
# for everything I've used it for.
#
# * That whole ninja & clang thing? We could support other configs if someone
# were willing to write the correct commands and a parser.
#
# * This has only been tested on gPrecise.
import os
import os.path
import re
import shlex
import subprocess
import sys
# A dictionary mapping Clang binary path to a list of Clang command line
# arguments that specify the system include paths. It is used as a cache of the
# system include options since these options aren't expected to change per
# source file for the same clang binary. SystemIncludeDirectoryFlags() updates
# this map each time it runs a Clang binary to determine system include paths.
#
# Entries look like:
# '/home/username/my-llvm/bin/clang++': ['-isystem',
# '/home/username/my-llvm/include', '-isystem', '/usr/include']
_clang_system_include_map = {}
# Flags from YCM's default config.
_default_flags = [
'-DUSE_CLANG_COMPLETER',
'-std=c++11',
'-x',
'c++',
]
def FallbackSystemIncludeDirectoryFlags():
"""Returns a best guess list of system include directory flags for Clang.
If Ninja doesn't give us a build step that specifies a Clang invocation or if
something goes wrong while determining the system include paths, then this
function can be used to determine some set of values that's better than
nothing.
Returns:
(List of Strings) Compiler flags that specify the system include paths.
"""
if _clang_system_include_map:
return _clang_system_include_map.itervalues().next()
return []
def SystemIncludeDirectoryFlags(clang_binary, clang_flags):
"""Determines compile flags for specifying system include directories.
Use as a workaround for https://github.com/Valloric/YouCompleteMe/issues/303
Caches the results of determining the system include directories in
_clang_system_include_map. Subsequent calls to SystemIncludeDirectoryFlags()
uses the cached results for the same binary even if |clang_flags| differ.
Args:
clang_binary: (String) Path to clang binary.
clang_flags: (List of Strings) List of additional flags to clang. It may
affect the choice of system include directories if -stdlib= is specified.
_default_flags are always included in the list of flags passed to clang.
Returns:
(List of Strings) Compile flags to append.
"""
if clang_binary in _clang_system_include_map:
return _clang_system_include_map[clang_binary]
all_clang_flags = [] + _default_flags
all_clang_flags += [flag for flag in clang_flags
if flag.startswith('-std=') or flag.startswith('-stdlib=')]
all_clang_flags += ['-v', '-E', '-']
try:
with open(os.devnull, 'rb') as DEVNULL:
output = subprocess.check_output([clang_binary] + all_clang_flags,
stdin=DEVNULL, stderr=subprocess.STDOUT)
except:
# Even though we couldn't figure out the flags for the given binary, if we
# have results from another one, we'll use that. This logic assumes that the
# list of default system directories for one binary can be used with
# another.
return FallbackSystemIncludeDirectoryFlags()
includes_regex = r'#include <\.\.\.> search starts here:\s*' \
r'(.*?)End of search list\.'
includes = re.search(includes_regex, output.decode(), re.DOTALL).group(1)
system_include_flags = []
for path in includes.splitlines():
path = path.strip()
if os.path.isdir(path):
system_include_flags.append('-isystem')
system_include_flags.append(path)
if system_include_flags:
_clang_system_include_map[clang_binary] = system_include_flags
return system_include_flags
def PathExists(*args):
return os.path.exists(os.path.join(*args))
def FindChromeSrcFromFilename(filename):
"""Searches for the root of the Chromium checkout.
Simply checks parent directories until it finds .gclient and src/.
Args:
filename: (String) Path to source file being edited.
Returns:
(String) Path of 'src/', or None if unable to find.
"""
curdir = os.path.normpath(os.path.dirname(filename))
while not (os.path.basename(os.path.realpath(curdir)) == 'src'
and PathExists(curdir, 'DEPS')
and (PathExists(curdir, '..', '.gclient')
or PathExists(curdir, '.git'))):
nextdir = os.path.normpath(os.path.join(curdir, '..'))
if nextdir == curdir:
return None
curdir = nextdir
return curdir
def GetDefaultCppFile(chrome_root, filename):
"""Returns the default target file to use for |filename|.
The default target is some source file that is known to exist and loosely
related to |filename|. Compile flags used to build the default target is
assumed to be a close-enough approximation for building |filename|.
Args:
chrome_root: (String) Absolute path to the root of Chromium checkout.
filename: (String) Absolute path to the target source file.
Returns:
(String) Absolute path to substitute target file.
"""
blink_root = os.path.join(chrome_root, 'third_party', 'WebKit')
if filename.startswith(blink_root):
return os.path.join(blink_root, 'Source', 'core', 'Init.cpp')
else:
return os.path.join(chrome_root, 'base', 'logging.cc')
def GetBuildTargetForSourceFile(chrome_root, filename):
"""Returns a build target corresponding to |filename|.
Args:
chrome_root: (String) Absolute path to the root of Chromium checkout.
filename: (String) Absolute path to the target source file.
Returns:
(String) Absolute path to build target.
"""
if filename.endswith('.h'):
# Header files can't be built. Instead, try to match a header file to its
# corresponding source file.
alternates = ['.cc', '.cpp', '.c']
for alt_extension in alternates:
alt_name = filename[:-2] + alt_extension
if os.path.exists(alt_name):
return alt_name
# Failing that, build a default file instead and assume that the resulting
# commandline options are valid for the .h file.
return GetDefaultCppFile(chrome_root, filename)
return filename
def GetClangCommandLineFromNinjaForFilename(out_dir, filename):
"""Returns the Clang command line for building |filename|
Asks ninja for the list of commands used to build |filename| and returns the
final Clang invocation.
Args:
out_dir: (String) Absolute path to ninja build output directory.
filename: (String) Absolute path to source file.
Returns:
(String) Clang command line or None if command line couldn't be determined.
"""
# Ninja needs the path to the source file relative to the output build
# directory.
rel_filename = os.path.relpath(os.path.realpath(filename), out_dir)
# Ask ninja how it would build our source file.
p = subprocess.Popen(['ninja', '-v', '-C', out_dir, '-t',
'commands', rel_filename + '^'],
stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode:
return None
# Ninja might execute several commands to build something. We want the last
# clang command.
for line in reversed(stdout.split('\n')):
if 'clang' in line:
return line
return None
def GetNormalizedClangCommand(command, out_dir):
"""Gets the normalized Clang binary path if |command| is a Clang command.
Args:
command: (String) Clang command.
out_dir: (String) Absolute path the ninja build directory.
Returns:
(String or None)
None : if command is not a clang command.
Absolute path to clang binary : if |command| is an absolute or relative
path to clang. If relative, it is assumed to be relative to |out_dir|.
|command|: if command is a name of a binary.
"""
if command.endswith('clang++') or command.endswith('clang'):
if os.path.basename(command) == command:
return command
return os.path.normpath(os.path.join(out_dir, command))
return None
def GetClangOptionsFromCommandLine(clang_commandline, out_dir,
additional_flags):
"""Extracts relevant command line options from |clang_commandline|
Args:
clang_commandline: (String) Full Clang invocation.
out_dir: (String) Absolute path to ninja build directory. Relative paths in
the command line are relative to |out_dir|.
additional_flags: (List of String) Additional flags to return.
Returns:
((List of Strings), (List of Strings)) The first item in the tuple is a list
of command line flags for this source file. The second item in the tuple is
a list of command line flags that define the system include paths. Either or
both can be empty.
"""
chrome_flags = [] + additional_flags
system_include_flags = []
# Parse flags that are important for YCM's purposes.
clang_tokens = shlex.split(clang_commandline)
for flag in clang_tokens:
if flag.startswith('-I'):
# Relative paths need to be resolved, because they're relative to the
# output dir, not the source.
if flag[2] == '/':
chrome_flags.append(flag)
else:
abs_path = os.path.normpath(os.path.join(out_dir, flag[2:]))
chrome_flags.append('-I' + abs_path)
elif flag.startswith('-std'):
chrome_flags.append(flag)
elif flag.startswith('-') and flag[1] in 'DWFfmO':
if flag == '-Wno-deprecated-register' or flag == '-Wno-header-guard':
# These flags causes libclang (3.3) to crash. Remove it until things
# are fixed.
continue
chrome_flags.append(flag)
# Assume that the command for invoking clang++ looks like one of the
# following:
# 1) /path/to/clang/clang++ arguments
# 2) /some/wrapper /path/to/clang++ arguments
#
# We'll look at the first two tokens on the command line to see if they look
# like Clang commands, and if so use it to determine the system include
# directory flags.
for command in clang_tokens[0:2]:
normalized_command = GetNormalizedClangCommand(command, out_dir)
if normalized_command:
system_include_flags += SystemIncludeDirectoryFlags(normalized_command,
chrome_flags)
break
return (chrome_flags, system_include_flags)
def GetClangOptionsFromNinjaForFilename(chrome_root, filename):
"""Returns the Clang command line options needed for building |filename|.
Command line options are based on the command used by ninja for building
|filename|. If |filename| is a .h file, uses its companion .cc or .cpp file.
If a suitable companion file can't be located or if ninja doesn't know about
|filename|, then uses default source files in Blink and Chromium for
determining the commandline.
Args:
chrome_root: (String) Path to src/.
filename: (String) Absolute path to source file being edited.
Returns:
((List of Strings), (List of Strings)) The first item in the tuple is a list
of command line flags for this source file. The second item in the tuple is
a list of command line flags that define the system include paths. Either or
both can be empty.
"""
if not chrome_root:
return ([],[])
# Generally, everyone benefits from including Chromium's src/, because all of
# Chromium's includes are relative to that.
additional_flags = ['-I' + os.path.join(chrome_root)]
# Version of Clang used to compile Chromium can be newer then version of
# libclang that YCM uses for completion. So it's possible that YCM's libclang
# doesn't know about some used warning options, which causes compilation
# warnings (and errors, because of '-Werror');
additional_flags.append('-Wno-unknown-warning-option')
sys.path.append(os.path.join(chrome_root, 'tools', 'vim'))
from ninja_output import GetNinjaOutputDirectory
out_dir = os.path.realpath(GetNinjaOutputDirectory(chrome_root))
clang_line = GetClangCommandLineFromNinjaForFilename(
out_dir, GetBuildTargetForSourceFile(chrome_root, filename))
if not clang_line:
# If ninja didn't know about filename or it's companion files, then try a
# default build target. It is possible that the file is new, or build.ninja
# is stale.
clang_line = GetClangCommandLineFromNinjaForFilename(
out_dir, GetDefaultCppFile(chrome_root, filename))
return GetClangOptionsFromCommandLine(clang_line, out_dir, additional_flags)
def FlagsForFile(filename):
"""This is the main entry point for YCM. Its interface is fixed.
Args:
filename: (String) Path to source file being edited.
Returns:
(Dictionary)
'flags': (List of Strings) Command line flags.
'do_cache': (Boolean) True if the result should be cached.
"""
abs_filename = os.path.abspath(filename)
chrome_root = FindChromeSrcFromFilename(abs_filename)
(chrome_flags, system_include_flags) = GetClangOptionsFromNinjaForFilename(
chrome_root, abs_filename)
# If either chrome_flags or system_include_flags could not be determined, then
# assume that was due to a transient failure. Preventing YCM from caching the
# flags allows us to try to determine the flags again.
should_cache_flags_for_file = \
bool(chrome_flags) and bool(system_include_flags)
if not system_include_flags:
system_include_flags = FallbackSystemIncludeDirectoryFlags()
final_flags = _default_flags + chrome_flags + system_include_flags
return {
'flags': final_flags,
'do_cache': should_cache_flags_for_file
}
" Copyright (c) 2014 The Chromium Authors. All rights reserved.
" Use of this source code is governed by a BSD-style license that can be
" found in the LICENSE file.
" Binds cmd-shift-i (on Mac) or ctrl-shift-i (elsewhere) to invoking
" clang-format.py.
" It will format the current selection (and if there's no selection, the
" current line.)
let s:script = expand('<sfile>:p:h') .
\'/../../buildtools/clang_format/script/clang-format.py'
if has('mac')
execute "map <D-I> :pyf " . s:script . "<CR>"
execute "imap <D-I> <ESC>:pyf " . s:script . "<CR>i"
else
execute "map <C-I> :pyf " . s:script . "<CR>"
execute "imap <C-I> <ESC>:pyf " . s:script . "<CR>i"
endif
" To get syntax highlighting and tab settings for gyp(i) and DEPS files,
" add the following to your .vimrc file:
" so /path/to/src/tools/vim/filetypes.vim
augroup filetype
au! BufRead,BufNewFile *.gyp set filetype=python expandtab tabstop=2 shiftwidth=2
au! BufRead,BufNewFile *.gypi set filetype=python expandtab tabstop=2 shiftwidth=2
au! BufRead,BufNewFile DEPS set filetype=python expandtab tabstop=2 shiftwidth=2
augroup END
" Copyright 2015 The Chromium Authors. All rights reserved.
" Use of this source code is governed by a BSD-style license that can be
" found in the LICENSE file.
" We take care to preserve the user's fileencodings and fileformats,
" because those settings are global (not buffer local), yet we want
" to override them for loading mojom files, which should be UTF-8.
let s:current_fileformats = ''
let s:current_fileencodings = ''
" define fileencodings to open as utf-8 encoding even if it's ascii.
function! s:mojomfiletype_pre()
let s:current_fileformats = &g:fileformats
let s:current_fileencodings = &g:fileencodings
set fileencodings=utf-8 fileformats=unix
setlocal filetype=mojom
endfunction
" restore fileencodings as others
function! s:mojomfiletype_post()
let &g:fileformats = s:current_fileformats
let &g:fileencodings = s:current_fileencodings
endfunction
au BufNewFile *.mojom setlocal filetype=mojom fileencoding=utf-8 fileformat=unix
au BufRead *.mojom call s:mojomfiletype_pre()
au BufReadPost *.mojom call s:mojomfiletype_post()
" Copyright 2015 The Chromium Authors. All rights reserved.
" Use of this source code is governed by a BSD-style license that can be
" found in the LICENSE file.
" Vim syntax file " Language: Mojom
" To get syntax highlighting for .mojom files, add the following to your .vimrc
" file:
" set runtimepath^=/path/to/src/tools/vim/mojom
syn case match
syntax region mojomFold start="{" end="}" transparent fold
" keyword definitions
syntax keyword mojomType bool int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double array
syntax match mojomImport "^\(import\)\s"
syntax keyword mojomKeyword const module interface enum struct union
syntax match mojomOperator /=>/
syntax match mojomOperator /?/
" Comments
syntax keyword mojomTodo contained TODO FIXME XXX
syntax region mojomComment start="/\*" end="\*/" contains=mojomTodo,mojomDocLink,@Spell
syntax match mojomLineComment "//.*" contains=mojomTodo,@Spell
syntax match mojomLineDocComment "///.*" contains=mojomTodo,mojomDocLink,@Spell
syntax region mojomDocLink contained start=+\[+ end=+\]+
" Strings
syn region mojomString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=@Spell
hi def link mojomString String
" The default highlighting.
highlight default link mojomTodo Todo
highlight default link mojomComment Comment
highlight default link mojomLineComment Comment
highlight default link mojomLineDocComment Comment
highlight default link mojomDocLink SpecialComment
highlight default link mojomType Type
highlight default link mojomImport Include
highlight default link mojomKeyword Keyword
highlight default link mojomOperator Operator
let b:current_syntax = "mojom"
let b:spell_options = "contained"
syn sync minlines=500
let b:current_syntax = "mojom"
" Copyright (c) 2012 The Chromium Authors. All rights reserved.
" Use of this source code is governed by a BSD-style license that can be
" found in the LICENSE file.
"
" Adds a "Compile this file" function, using ninja. On Mac, binds Cmd-k to
" this command. On Windows, Ctrl-F7 (which is the same as the VS default).
" On Linux, <Leader>o, which is \o by default ("o"=creates .o files)
"
" Adds a "Build this target" function, using ninja. This is not bound
" to any key by default, but can be used via the :CrBuild command.
" It builds 'chrome' by default, but :CrBuild target1 target2 etc works as well.
"
" Requires that gyp has already generated build.ninja files, and that ninja is
" in your path (which it is automatically if depot_tools is in your path).
"
" Add the following to your .vimrc file:
" so /path/to/src/tools/vim/ninja-build.vim
python << endpython
import os
import vim
def path_to_current_buffer():
"""Returns the absolute path of the current buffer."""
return vim.current.buffer.name
def path_to_source_root():
"""Returns the absolute path to the chromium source root."""
candidate = os.path.dirname(path_to_current_buffer())
# This is a list of files that need to identify the src directory. The shorter
# it is, the more likely it's wrong (checking for just "build/common.gypi"
# would find "src/v8" for files below "src/v8", as "src/v8/build/common.gypi"
# exists). The longer it is, the more likely it is to break when we rename
# directories.
fingerprints = ['chrome', 'net', 'v8', 'build', 'skia']
while candidate and not all(
[os.path.isdir(os.path.join(candidate, fp)) for fp in fingerprints]):
candidate = os.path.dirname(candidate)
return candidate
def path_to_build_dir(configuration):
"""Returns <chrome_root>/<output_dir>/(Release|Debug)."""
chrome_root = path_to_source_root()
sys.path.append(os.path.join(chrome_root, 'tools', 'vim'))
from ninja_output import GetNinjaOutputDirectory
return GetNinjaOutputDirectory(chrome_root, configuration)
def compute_ninja_command_for_current_buffer(configuration=None):
"""Returns the shell command to compile the file in the current buffer."""
build_dir = path_to_build_dir(configuration)
# ninja needs filepaths for the ^ syntax to be relative to the
# build directory.
file_to_build = path_to_current_buffer()
file_to_build = os.path.relpath(file_to_build, build_dir)
build_cmd = ' '.join(['ninja', '-C', build_dir, file_to_build + '^'])
if sys.platform == 'win32':
# Escape \ for Vim, and ^ for both Vim and shell.
build_cmd = build_cmd.replace('\\', '\\\\').replace('^', '^^^^')
vim.command('return "%s"' % build_cmd)
def compute_ninja_command_for_targets(targets='', configuration=None):
build_cmd = ' '.join(['ninja', '-C', path_to_build_dir(configuration),
targets])
vim.command('return "%s"' % build_cmd)
endpython
fun! s:MakeWithCustomCommand(build_cmd)
let l:oldmakepgr = &makeprg
let &makeprg=a:build_cmd
if exists(':Make') == 2
Make
else
silent make | cwindow
endif
if !has('gui_running')
redraw!
endif
let &makeprg = l:oldmakepgr
endfun
fun! s:NinjaCommandForCurrentBuffer()
python compute_ninja_command_for_current_buffer()
endfun
fun! s:NinjaCommandForTargets(targets)
python compute_ninja_command_for_targets(vim.eval('a:targets'))
endfun
fun! CrCompileFile()
call s:MakeWithCustomCommand(s:NinjaCommandForCurrentBuffer())
endfun
fun! CrBuild(...)
let l:targets = a:0 > 0 ? join(a:000, ' ') : ''
if (l:targets !~ '\i')
let l:targets = 'chrome'
endif
call s:MakeWithCustomCommand(s:NinjaCommandForTargets(l:targets))
endfun
command! CrCompileFile call CrCompileFile()
command! -nargs=* CrBuild call CrBuild(<q-args>)
if has('mac')
map <D-k> :CrCompileFile<cr>
imap <D-k> <esc>:CrCompileFile<cr>
elseif has('win32')
map <C-F7> :CrCompileFile<cr>
imap <C-F7> <esc>:CrCompileFile<cr>
elseif has('unix')
map <Leader>o :CrCompileFile<cr>
endif
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import os.path
import re
def GetNinjaOutputDirectory(chrome_root, configuration=None):
"""Returns <chrome_root>/<output_dir>/(Release|Debug).
The output_dir is detected in the following ways, in order of precedence:
1. CHROMIUM_OUT_DIR environment variable.
2. GYP_GENERATOR_FLAGS environment variable output_dir property.
3. Symlink target, if src/out is a symlink.
4. Most recently modified (e.g. built) directory called out or out_*.
The configuration chosen is the one most recently generated/built, but can be
overriden via the <configuration> parameter."""
output_dirs = []
if ('CHROMIUM_OUT_DIR' in os.environ and
os.path.isdir(os.path.join(chrome_root, os.environ['CHROMIUM_OUT_DIR']))):
output_dirs = [os.environ['CHROMIUM_OUT_DIR']]
if not output_dirs:
generator_flags = os.getenv('GYP_GENERATOR_FLAGS', '').split(' ')
for flag in generator_flags:
name_value = flag.split('=', 1)
if (len(name_value) == 2 and name_value[0] == 'output_dir' and
os.path.isdir(os.path.join(chrome_root, name_value[1]))):
output_dirs = [name_value[1]]
if not output_dirs:
out = os.path.join(chrome_root, 'out')
if os.path.islink(out):
out_target = os.path.join(os.path.dirname(out), os.readlink(out))
if os.path.exists(out_target):
output_dirs = [out_target]
if not output_dirs:
for f in os.listdir(chrome_root):
if (re.match('out(?:$|_)', f) and
os.path.isdir(os.path.join(chrome_root, f))):
output_dirs.append(f)
configs = [configuration] if configuration else ['Debug', 'Release']
output_paths = [os.path.join(chrome_root, out_dir, config)
for out_dir in output_dirs for config in configs]
def approx_directory_mtime(path):
if not os.path.exists(path):
return -1
# This is a heuristic; don't recurse into subdirectories.
paths = [path] + [os.path.join(path, f) for f in os.listdir(path)]
return max(os.path.getmtime(p) for p in paths)
return max(output_paths, key=approx_directory_mtime)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment