Import Cobalt 13.103922 Change-Id: I06559c46741bb6050da0b0677b55c71bf6880784
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc index 4322073..a1f944d 100644 --- a/src/cobalt/browser/browser_module.cc +++ b/src/cobalt/browser/browser_module.cc
@@ -1269,7 +1269,9 @@ // render tree resources either. main_web_module_layer_->Reset(); splash_screen_layer_->Reset(); +#if defined(ENABLE_DEBUG_CONSOLE) debug_console_layer_->Reset(); +#endif // defined(ENABLE_DEBUG_CONSOLE) #if defined(ENABLE_GPU_ARRAY_BUFFER_ALLOCATOR) // Note that the following function call will leak the GPU memory allocated.
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h index 6f95f5c..2ecdbcf 100644 --- a/src/cobalt/browser/browser_module.h +++ b/src/cobalt/browser/browser_module.h
@@ -396,8 +396,10 @@ // Manages the three render trees, combines and renders them. RenderTreeCombiner render_tree_combiner_; scoped_ptr<RenderTreeCombiner::Layer> main_web_module_layer_; - scoped_ptr<RenderTreeCombiner::Layer> debug_console_layer_; scoped_ptr<RenderTreeCombiner::Layer> splash_screen_layer_; +#if defined(ENABLE_DEBUG_CONSOLE) + scoped_ptr<RenderTreeCombiner::Layer> debug_console_layer_; +#endif // defined(ENABLE_DEBUG_CONSOLE) #if defined(ENABLE_SCREENSHOT) // Helper object to create screen shots of the last layout tree.
diff --git a/src/cobalt/browser/testdata/mtm-demo/README.txt b/src/cobalt/browser/testdata/mtm-demo/README.txt deleted file mode 100644 index 5368357..0000000 --- a/src/cobalt/browser/testdata/mtm-demo/README.txt +++ /dev/null
@@ -1,37 +0,0 @@ -These test whether the presence of the CSS MTM filter affect the path taken in -rendering the video replaced box. <normal.html> has a video tag without the -filter, while <mtm.html> has a video with the filter applied to it. - -To test locally, all 3 of mtm.html, normal.html and progressive.mp4 have to be -hosted on a server that supports HTTP RANGE header, which is needed for video to -be loaded correctly. One such server is the extension to the Python -SimpleHTTPServer at https://github.com/danvk/RangeHTTPServer (run from this -directory, "cobalt/src/cobalt/browser/testdata/mtm-demo/"): - - $ sudo apt-get install python-pip - $ pip install --user rangehttpserver - $ python -m RangeHTTPServer - -Test video without the MTM filter (should render normally, run from cobalt/src -directory): - - $ out/linux-x64x11_debug/cobalt --csp_mode=disable --allow_http --url=http://localhost:8000/normal.html - -Test the video with the MTM filter (should NOT render in its bounding box in the -document, and in the presence of the correct rasterizer, should be rendered onto -its own texture off the main UI layout): - - $ out/linux-x64x11_debug/cobalt --csp_mode=disable --allow_http --url=http://localhost:8000/mtm.html - -There is also the option of using the google cloud utils and the cloud storage -to publish these files, as is done with the other demos. Care should be taken -that nothing confidential gets uploaded with these files. "public-read" is -needed in the ACL because linking and video srcing does not work without it. - -A bucket specifically for this demo already exists at "gs://yt-cobalt-mtm-test", -but uploading to it often might be problematic since buckets are not verison- -controlled: - - $ gsutil cp -a public-read cobalt/browser/testdata/mtm-demo/normal.html cobalt/browser/testdata/mtm-demo/mtm.html cobalt/browser/testdata/mtm-demo/progressive.mp4 gs://yt-cobalt-mtm-test/ - $ out/linux-x64x11_debug/cobalt --csp_mode=disable --url=https://storage.googleapis.com/yt-cobalt-mtm-test/mtm.html - $ out/linux-x64x11_debug/cobalt --csp_mode=disable --url=https://storage.googleapis.com/yt-cobalt-mtm-test/normal.html
diff --git a/src/cobalt/browser/testdata/mtm-demo/mtm.html b/src/cobalt/browser/testdata/mtm-demo/mtm.html index 6877674..e91a3cc 100644 --- a/src/cobalt/browser/testdata/mtm-demo/mtm.html +++ b/src/cobalt/browser/testdata/mtm-demo/mtm.html
@@ -1,28 +1,77 @@ <!DOCTYPE html> <html> + <head> - <title>mtm Demo</title> + <title>Map-To-Mesh Demo</title> + <style> - body { - background-color: rgb(255, 255, 255); - color: #0047ab; - font-size: 100px; + #v { + width: 100%; + height: 100%; + filter: map-to-mesh(equirectangular, 100deg 60deg, + matrix3d(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1)); } - .vid { - margin: 100px; - border: 10px solid blue; - width: 960px; - height: 540px; - filter: -cobalt-mtm(url(projection.msh), 100deg 60deg, - matrix3d(1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1)); + + .instructions { + position: absolute; + left: 0; + background-color: white; + color: black; } </style> + + <script> + var degreesPerSecond = 90; + // The following mappings are done in this order: + // Up, Down, Left, Right + + // Direction keys + camera3D.createKeyMapping(38, camera3D.DOM_CAMERA_PITCH, degreesPerSecond); + camera3D.createKeyMapping(40, camera3D.DOM_CAMERA_PITCH, -degreesPerSecond); + camera3D.createKeyMapping(37, camera3D.DOM_CAMERA_YAW, degreesPerSecond); + camera3D.createKeyMapping(39, camera3D.DOM_CAMERA_YAW, -degreesPerSecond); + + // DPAD + camera3D.createKeyMapping( + 0x800C, camera3D.DOM_CAMERA_PITCH, degreesPerSecond); + camera3D.createKeyMapping( + 0x800D, camera3D.DOM_CAMERA_PITCH, -degreesPerSecond); + camera3D.createKeyMapping( + 0x800E, camera3D.DOM_CAMERA_YAW, degreesPerSecond); + camera3D.createKeyMapping( + 0x800F, camera3D.DOM_CAMERA_YAW, -degreesPerSecond); + + // Left joystick + camera3D.createKeyMapping( + 0x8011, camera3D.DOM_CAMERA_PITCH, degreesPerSecond); + camera3D.createKeyMapping( + 0x8012, camera3D.DOM_CAMERA_PITCH, -degreesPerSecond); + camera3D.createKeyMapping( + 0x8013, camera3D.DOM_CAMERA_YAW, degreesPerSecond); + camera3D.createKeyMapping( + 0x8014, camera3D.DOM_CAMERA_YAW, -degreesPerSecond); + + // Right joystick + camera3D.createKeyMapping( + 0x8015, camera3D.DOM_CAMERA_PITCH, degreesPerSecond); + camera3D.createKeyMapping( + 0x8016, camera3D.DOM_CAMERA_PITCH, -degreesPerSecond); + camera3D.createKeyMapping( + 0x8017, camera3D.DOM_CAMERA_YAW, degreesPerSecond); + camera3D.createKeyMapping( + 0x8018, camera3D.DOM_CAMERA_YAW, -degreesPerSecond); + </script> </head> + <body> - <div>Mtm Demo!!!</div> - <video autoplay loop id="v" class="vid" src="progressive.mp4"></video> + <video autoplay loop id="v" src="progressive.mp4"></video> + <div class="instructions"> + Use either the keyboard keys, direction keys, or analog joystick/thumbstick + to look around. + </div> </body> + </html>
diff --git a/src/cobalt/browser/testdata/mtm-demo/progressive.mp4 b/src/cobalt/browser/testdata/mtm-demo/progressive.mp4 deleted file mode 100644 index 2686a9b..0000000 --- a/src/cobalt/browser/testdata/mtm-demo/progressive.mp4 +++ /dev/null Binary files differ
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id index 36f609f..d4d1d7c 100644 --- a/src/cobalt/build/build.id +++ b/src/cobalt/build/build.id
@@ -1 +1 @@ -103164 \ No newline at end of file +103922 \ No newline at end of file
diff --git a/src/cobalt/cssom/computed_style.cc b/src/cobalt/cssom/computed_style.cc index a59143a..a26c451 100644 --- a/src/cobalt/cssom/computed_style.cc +++ b/src/cobalt/cssom/computed_style.cc
@@ -613,6 +613,8 @@ class ComputedHeightProvider : public NotReachedPropertyValueVisitor { public: ComputedHeightProvider(const PropertyValue* parent_computed_height, + const PropertyValue* parent_computed_top, + const PropertyValue* parent_computed_bottom, const LengthValue* computed_font_size, const LengthValue* root_computed_font_size, const math::Size& viewport_size, bool out_of_flow); @@ -627,6 +629,8 @@ private: const PropertyValue* parent_computed_height_; + const PropertyValue* parent_computed_top_; + const PropertyValue* parent_computed_bottom_; const LengthValue* computed_font_size_; const LengthValue* root_computed_font_size_; const math::Size& viewport_size_; @@ -639,10 +643,14 @@ ComputedHeightProvider::ComputedHeightProvider( const PropertyValue* parent_computed_height, + const PropertyValue* parent_computed_top, + const PropertyValue* parent_computed_bottom, const LengthValue* computed_font_size, const LengthValue* root_computed_font_size, const math::Size& viewport_size, bool out_of_flow) : parent_computed_height_(parent_computed_height), + parent_computed_top_(parent_computed_top), + parent_computed_bottom_(parent_computed_bottom), computed_font_size_(computed_font_size), root_computed_font_size_(root_computed_font_size), viewport_size_(viewport_size), @@ -725,7 +733,10 @@ // (i.e., it depends on content height), and this element is not absolutely // positioned, the value computes to "auto". // https://www.w3.org/TR/CSS21/visudet.html#the-height-property - computed_height_ = (parent_computed_height_ == auto_value && !out_of_flow_) + computed_height_ = (parent_computed_height_ == auto_value && + (parent_computed_top_ == auto_value || + parent_computed_bottom_ == auto_value) && + !out_of_flow_) ? auto_value : percentage; } @@ -2858,7 +2869,9 @@ } break; case kHeightProperty: { ComputedHeightProvider height_provider( - parent_computed_style_.height().get(), GetFontSize(), + parent_computed_style_.height().get(), + parent_computed_style_.top().get(), + parent_computed_style_.bottom().get(), GetFontSize(), GetRootFontSize(), GetViewportSizeOnePercent(), IsAbsolutelyPositioned()); (*value)->Accept(&height_provider);
diff --git a/src/cobalt/dom/url_utils.cc b/src/cobalt/dom/url_utils.cc index df204d1..57604bd 100644 --- a/src/cobalt/dom/url_utils.cc +++ b/src/cobalt/dom/url_utils.cc
@@ -14,9 +14,76 @@ #include "cobalt/dom/url_utils.h" +namespace { +// Returns true if the url can have non-opaque origin. +// Blob URLs needs to be pre-processed. +bool NonBlobURLCanHaveTupleOrigin(const GURL& url) { + if (url.SchemeIs("https")) { + return true; + } else if (url.SchemeIs("http")) { + return true; + } else if (url.SchemeIs("ftp")) { + return true; + } else if (url.SchemeIs("ws")) { + return true; + } else if (url.SchemeIs("wss")) { + return true; + } + return false; +} +// Returns false if url should be opaque. +// Otherwise, extract origin tuple from the url and assemble them as a string +// for easier access and comparison. +bool NonBlobURLGetOriginStr(const GURL& url, std::string* output) { + if (!NonBlobURLCanHaveTupleOrigin(url)) { + return false; + } + *output = url.scheme() + "://" + url.host() + + (url.has_port() ? ":" + url.port() : ""); + return true; +} +} // namespace + namespace cobalt { namespace dom { +URLUtils::Origin::Origin() : is_opaque_(true) {} + +URLUtils::Origin::Origin(const GURL& url) : is_opaque_(false) { + if (url.is_valid() && url.has_scheme() && url.has_host()) { + if (url.SchemeIs("blob")) { + // Let path_url be the result of parsing URL's path. + // Return a new opaque origin, if url is failure, and url's origin + // otherwise. + GURL path_url(url.path()); + if (path_url.is_valid() && path_url.has_host() && path_url.has_scheme() && + NonBlobURLGetOriginStr(path_url, &origin_str_)) { + return; + } + } else if (NonBlobURLGetOriginStr(url, &origin_str_)) { + // Assign a tuple origin if given url is allowed to have one. + return; + } + } + // Othwise, return a new opaque origin. + is_opaque_ = true; +} + +std::string URLUtils::Origin::SerializedOrigin() const { + if (is_opaque_) { + return "null"; + } + return origin_str_; +} + +bool URLUtils::Origin::operator==(const Origin& rhs) const { + if (is_opaque_ || rhs.is_opaque_) { + return false; + } else { + return origin_str_ == rhs.origin_str_; + } +} + URLUtils::URLUtils(const GURL& url, bool is_opaque) : url_(url), origin_(is_opaque ? Origin() : Origin(url)) {} URLUtils::URLUtils(const GURL& url, const UpdateStepsCallback& update_steps,
diff --git a/src/cobalt/dom/url_utils.h b/src/cobalt/dom/url_utils.h index af3f3ad..aa66825 100644 --- a/src/cobalt/dom/url_utils.h +++ b/src/cobalt/dom/url_utils.h
@@ -20,36 +20,6 @@ #include "base/callback.h" #include "googleurl/src/gurl.h" -namespace { -// Returns true if the url can have non-opaque origin. -// Blob URLs needs to be pre-processed. -bool NonBlobURLCanHaveTupleOrigin(const GURL& url) { - if (url.SchemeIs("https")) { - return true; - } else if (url.SchemeIs("http")) { - return true; - } else if (url.SchemeIs("ftp")) { - return true; - } else if (url.SchemeIs("ws")) { - return true; - } else if (url.SchemeIs("wss")) { - return true; - } - return false; -} -// Returns false if url should be opaque. -// Otherwise, extract origin tuple from the url and assemble them as a string -// for easier access and comparison. -bool NonBlobURLGetOriginStr(const GURL& url, std::string* output) { - if (!NonBlobURLCanHaveTupleOrigin(url)) { - return false; - } - *output = url.scheme() + "://" + url.host() + - (url.has_port() ? ":" + url.port() : ""); - return true; -} -} // namespace - namespace cobalt { namespace dom { @@ -69,48 +39,19 @@ class Origin { public: // To create an opaque origin, use Origin(). - Origin() : is_opaque_(true) {} + Origin(); // Initialize an origin to the url's origin. // https://url.spec.whatwg.org/#concept-url-origin - Origin(const GURL& url) : is_opaque_(false) { - if (url.is_valid() && url.has_scheme() && url.has_host()) { - if (url.SchemeIs("blob")) { - // Let path_url be the result of parsing URL's path. - // Return a new opaque origin, if url is failure, and url's origin - // otherwise. - GURL path_url(url.path()); - if (path_url.is_valid() && path_url.has_host() && - path_url.has_scheme() && - NonBlobURLGetOriginStr(path_url, &origin_str_)) { - return; - } - } else if (NonBlobURLGetOriginStr(url, &origin_str_)) { - // Assign a tuple origin if given url is allowed to have one. - return; - } - } - // Othwise, return a new opaque origin. - is_opaque_ = true; - } + explicit Origin(const GURL& url); // https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin - std::string SerializedOrigin() const { - if (is_opaque_) { - return "null"; - } - return origin_str_; - } + std::string SerializedOrigin() const; + bool is_opaque() const { return is_opaque_; } // Only document has an origin and no elements inherit document's origin, so // opaque origin comparison can always return false. // https://html.spec.whatwg.org/multipage/origin.html#same-origin - bool operator==(const Origin& rhs) { - if (is_opaque_ || rhs.is_opaque_) { - return false; - } else { - return origin_str_ == rhs.origin_str_; - } - } + bool operator==(const Origin& rhs) const; // Returns true if two origins are different(cross-origin). - bool operator!=(const Origin& rhs) { return !(*this == rhs); } + bool operator!=(const Origin& rhs) const { return !(*this == rhs); } private: bool is_opaque_;
diff --git a/src/cobalt/layout/block_container_box.cc b/src/cobalt/layout/block_container_box.cc index 80d1edd..557b666 100644 --- a/src/cobalt/layout/block_container_box.cc +++ b/src/cobalt/layout/block_container_box.cc
@@ -110,8 +110,14 @@ // it depends on content height), and this element is not absolutely // positioned, the value [of "height"] computes to "auto". // https://www.w3.org/TR/CSS21/visudet.html#the-height-property - child_layout_params.containing_block_size.set_height( - maybe_height.value_or(LayoutUnit())); + if (maybe_height) { + child_layout_params.containing_block_size.set_height(*maybe_height); + } else if (maybe_top && maybe_bottom) { + child_layout_params.containing_block_size.set_height( + containing_block_size.height() - *maybe_top - *maybe_bottom); + } else { + child_layout_params.containing_block_size.set_height(LayoutUnit()); + } } scoped_ptr<FormattingContext> formatting_context = UpdateRectOfInFlowChildBoxes(child_layout_params);
diff --git a/src/cobalt/layout/box.cc b/src/cobalt/layout/box.cc index 38c644f..c8ed055 100644 --- a/src/cobalt/layout/box.cc +++ b/src/cobalt/layout/box.cc
@@ -547,21 +547,11 @@ render_tree::CompositionNode::Builder border_node_builder(border_box_offset); AnimateNode::Builder animate_node_builder; - base::optional<RoundedCorners> rounded_corners = ComputeRoundedCorners(); + const base::optional<RoundedCorners> rounded_corners = + ComputeRoundedCorners(); - // If we have rounded corners and a non-zero border, then we need to compute - // the "inner" rounded corners, as the ones specified by CSS apply to the - // outer border edge. - base::optional<RoundedCorners> padding_rounded_corners_if_different; - if (rounded_corners && !border_insets_.zero()) { - padding_rounded_corners_if_different = rounded_corners->Inset(math::InsetsF( - border_insets_.left().toFloat(), border_insets_.top().toFloat(), - border_insets_.right().toFloat(), border_insets_.bottom().toFloat())); - } - const base::optional<RoundedCorners>& padding_rounded_corners = - padding_rounded_corners_if_different - ? padding_rounded_corners_if_different - : rounded_corners; + const base::optional<RoundedCorners> padding_rounded_corners = + ComputePaddingRoundedCorners(rounded_corners); // The painting order is: // - background color. @@ -594,8 +584,8 @@ } RenderAndAnimateBorder(rounded_corners, &border_node_builder, &animate_node_builder); - RenderAndAnimateBoxShadow(rounded_corners, &border_node_builder, - &animate_node_builder); + RenderAndAnimateBoxShadow(rounded_corners, padding_rounded_corners, + &border_node_builder, &animate_node_builder); } const bool overflow_hidden = @@ -744,8 +734,7 @@ if (rounded_corners) { rect_node_builder->rounded_corners = - scoped_ptr<RoundedCorners>(new RoundedCorners( - rounded_corners->Normalize(rect_node_builder->rect))); + scoped_ptr<RoundedCorners>(new RoundedCorners(*rounded_corners)); } } @@ -834,8 +823,7 @@ if (rounded_corners) { rect_node_builder->rounded_corners = - scoped_ptr<RoundedCorners>(new RoundedCorners( - rounded_corners->Normalize(rect_node_builder->rect))); + scoped_ptr<RoundedCorners>(new RoundedCorners(*rounded_corners)); } } @@ -1225,7 +1213,7 @@ } // namespace -base::optional<render_tree::RoundedCorners> Box::ComputeRoundedCorners() { +base::optional<render_tree::RoundedCorners> Box::ComputeRoundedCorners() const { UsedBorderRadiusProvider border_radius_provider(GetBorderBoxSize()); render_tree::RoundedCorner border_top_left_radius; render_tree::RoundedCorner border_top_right_radius; @@ -1269,13 +1257,36 @@ rounded_corners.emplace(border_top_left_radius, border_top_right_radius, border_bottom_right_radius, border_bottom_left_radius); + rounded_corners = + rounded_corners->Normalize(math::RectF(GetBorderBoxSize())); } return rounded_corners; } +base::optional<render_tree::RoundedCorners> Box::ComputePaddingRoundedCorners( + const base::optional<RoundedCorners>& rounded_corners) const { + base::optional<RoundedCorners> padding_rounded_corners_if_different; + + if (rounded_corners && !border_insets_.zero()) { + // If we have rounded corners and a non-zero border, then we need to + // compute the "inner" rounded corners, as the ones specified by CSS apply + // to the outer border edge. + padding_rounded_corners_if_different = rounded_corners->Inset(math::InsetsF( + border_insets_.left().toFloat(), border_insets_.top().toFloat(), + border_insets_.right().toFloat(), border_insets_.bottom().toFloat())); + } + + const base::optional<RoundedCorners>& padding_rounded_corners = + padding_rounded_corners_if_different + ? padding_rounded_corners_if_different + : rounded_corners; + return padding_rounded_corners; +} + void Box::RenderAndAnimateBoxShadow( - const base::optional<RoundedCorners>& rounded_corners, + const base::optional<RoundedCorners>& outer_rounded_corners, + const base::optional<RoundedCorners>& inner_rounded_corners, CompositionNode::Builder* border_node_builder, AnimateNode::Builder* animate_node_builder) { UNREFERENCED_PARAMETER(animate_node_builder); @@ -1327,9 +1338,13 @@ render_tree::RectShadowNode::Builder shadow_builder( math::RectF(rect_offset, shadow_rect_size), shadow, shadow_value->has_inset(), spread_radius); - if (rounded_corners) { - shadow_builder.rounded_corners = rounded_corners->Normalize( - shadow_builder.rect); + + if (outer_rounded_corners) { + if (shadow_value->has_inset()) { + shadow_builder.rounded_corners = inner_rounded_corners; + } else { + shadow_builder.rounded_corners = outer_rounded_corners; + } } // Finally, create our shadow node. @@ -1484,8 +1499,7 @@ // Apply rounded viewport filter to the background image. FilterNode::Builder filter_node_builder(background_node); filter_node_builder.viewport_filter = - ViewportFilter(image_frame, - rounded_corners->Normalize(image_frame)); + ViewportFilter(image_frame, *rounded_corners); background_node = new FilterNode(filter_node_builder); } @@ -1548,18 +1562,11 @@ scoped_refptr<render_tree::Node> Box::RenderAndAnimateOverflow( const scoped_refptr<render_tree::Node>& content_node, const math::Vector2dF& border_offset) { - base::optional<RoundedCorners> rounded_corners = ComputeRoundedCorners(); + const base::optional<RoundedCorners> rounded_corners = + ComputeRoundedCorners(); - base::optional<RoundedCorners> padding_rounded_corners_if_different; - if (rounded_corners && !border_insets_.zero()) { - padding_rounded_corners_if_different = rounded_corners->Inset(math::InsetsF( - border_insets_.left().toFloat(), border_insets_.top().toFloat(), - border_insets_.right().toFloat(), border_insets_.bottom().toFloat())); - } - const base::optional<RoundedCorners>& padding_rounded_corners = - padding_rounded_corners_if_different - ? padding_rounded_corners_if_different - : rounded_corners; + const base::optional<RoundedCorners> padding_rounded_corners = + ComputePaddingRoundedCorners(rounded_corners); return RenderAndAnimateOverflow(padding_rounded_corners, content_node, NULL, border_offset); @@ -1584,9 +1591,7 @@ border_node_offset.y() + border_top_width().toFloat(), padding_size.width(), padding_size.height())); if (rounded_corners) { - filter_node_builder.viewport_filter->set_rounded_corners( - rounded_corners->Normalize( - filter_node_builder.viewport_filter->viewport())); + filter_node_builder.viewport_filter->set_rounded_corners(*rounded_corners); } return scoped_refptr<render_tree::Node>(new FilterNode(filter_node_builder));
diff --git a/src/cobalt/layout/box.h b/src/cobalt/layout/box.h index 67056ab..dda5300 100644 --- a/src/cobalt/layout/box.h +++ b/src/cobalt/layout/box.h
@@ -699,8 +699,13 @@ // Updates used values of "padding" properties. void UpdatePaddings(const LayoutParams& layout_params); - // Computes the rounded corners (if there are any) from the border radii. - base::optional<render_tree::RoundedCorners> ComputeRoundedCorners(); + // Computes the normalized "outer" rounded corners (if there are any) from the + // border radii. + base::optional<render_tree::RoundedCorners> ComputeRoundedCorners() const; + + // Computes the corresponding "inner" rounded corners. + base::optional<render_tree::RoundedCorners> ComputePaddingRoundedCorners( + const base::optional<render_tree::RoundedCorners>& rounded_corners) const; // Called after TryPlaceEllipsisOrProcessPlacedEllipsis() determines that the // box is impacted by the ellipsis. This handles both determining the location @@ -736,7 +741,8 @@ RenderAndAnimateBackgroundImageResult RenderAndAnimateBackgroundImage( const base::optional<render_tree::RoundedCorners>& rounded_corners); void RenderAndAnimateBoxShadow( - const base::optional<render_tree::RoundedCorners>& rounded_corners, + const base::optional<render_tree::RoundedCorners>& outer_rounded_corners, + const base::optional<render_tree::RoundedCorners>& inner_rounded_corners, render_tree::CompositionNode::Builder* border_node_builder, render_tree::animations::AnimateNode::Builder* animate_node_builder);
diff --git a/src/cobalt/layout_tests/testdata/css-2-1/10-5-percentage-of-height-should-work-properly-with-top-and-bottom-expected.png b/src/cobalt/layout_tests/testdata/css-2-1/10-5-percentage-of-height-should-work-properly-with-top-and-bottom-expected.png new file mode 100644 index 0000000..6b01be2 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css-2-1/10-5-percentage-of-height-should-work-properly-with-top-and-bottom-expected.png Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/css-2-1/10-5-percentage-of-height-should-work-properly-with-top-and-bottom.html b/src/cobalt/layout_tests/testdata/css-2-1/10-5-percentage-of-height-should-work-properly-with-top-and-bottom.html new file mode 100644 index 0000000..3e23d27 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css-2-1/10-5-percentage-of-height-should-work-properly-with-top-and-bottom.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<!-- + | If the height of the child is a percent of the height of the containing + | block and the containing block's height is produced from top and bottom, + | the height of the child should be properly calculated. + | https://www.w3.org/TR/CSS21/visudet.html#the-height-property + | https://www.w3.org/TR/CSS21/visuren.html#propdef-top + | https://www.w3.org/TR/CSS21/visuren.html#propdef-bottom + --> +<html> +<head> + <style"> + body { + background-color: #FFFFFF; + } + .container { + position: absolute; + height: 300px; + width: 100px; + } + .top-bottom { + background-color: #EA4335; + position: absolute; + top: 10px; + bottom: 0px; + left: 10px; + width: 100px; + } + .percent-height { + background-color: #4285F4; + height: 100%; + position: relative; + } + </style> +</head> +<body> + <div class="container"> + <div class="top-bottom"> + <div class="percent-height"></div> + </div> + </div> +</body> +</html>
diff --git a/src/cobalt/layout_tests/testdata/css-2-1/layout_tests.txt b/src/cobalt/layout_tests/testdata/css-2-1/layout_tests.txt index 995b02a..37e4c1e 100644 --- a/src/cobalt/layout_tests/testdata/css-2-1/layout_tests.txt +++ b/src/cobalt/layout_tests/testdata/css-2-1/layout_tests.txt
@@ -43,6 +43,7 @@ 10-4-min-width-and-max-width-percentage-should-refer-containing-block-width 10-5-percentage-of-auto-height-on-absolute-element-should-compute-to-percentage 10-5-percentage-of-auto-height-should-compute-to-auto +10-5-percentage-of-height-should-work-properly-with-top-and-bottom 10-6-1-content-height-of-inline-boxes-matches-font-size 10-6-2-replaced-box-height 10-8-1-inline-box-with-non-normal-line-height-should-use-first-available-font-for-font-metrics
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border-and-inset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border-and-inset-shadow.html new file mode 100644 index 0000000..a46b00a --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border-and-inset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 2 values for the border radius for a box with a background color, + | a border and an inset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 100px; + box-shadow: 10px 10px #FF7F50 inset; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border-and-outset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border-and-outset-shadow.html new file mode 100644 index 0000000..1cc1359 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border-and-outset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 2 values for the border radius for a box with a background color, + | a border and an outset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 100px; + box-shadow: 10px 10px #FF7F50; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border.html new file mode 100644 index 0000000..63e2826 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-2-values-with-background-color-and-border.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- + | Setting 2 values for the border radius for a box with a background color + | and a border. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 100px; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border-and-inset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border-and-inset-shadow.html new file mode 100644 index 0000000..93ab665 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border-and-inset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 3 values for the border radius for a box with a background color, + | a border and in inset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 10px 120px 50px; + box-shadow: 10px 10px #FF7F50 inset; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html>
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border-and-outset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border-and-outset-shadow.html new file mode 100644 index 0000000..3e5517a --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border-and-outset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 3 values for the border radius for a box with a background color, + | a border and in outset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 10px 120px 50px; + box-shadow: 10px 10px #FF7F50; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border.html new file mode 100644 index 0000000..7d26761 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-3-values-with-background-color-and-border.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- + | Setting 3 values for the border radius for a box with a background color + | and a border. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 10px 120px 50px; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html>
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border-and-inset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border-and-inset-shadow.html new file mode 100644 index 0000000..4ec00df --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border-and-inset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 4 values for the border radius for a box with a background color, + | a border and an inset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 120px 40px 70px; + box-shadow: 10px 10px #FF7F50 inset; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border-and-outset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border-and-outset-shadow.html new file mode 100644 index 0000000..256fe37 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border-and-outset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 4 values for the border radius for a box with a background color, + | a border and an outset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 120px 40px 70px; + box-shadow: 10px 10px #FF7F50; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border.html new file mode 100644 index 0000000..c419580 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-4-values-with-background-color-and-border.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- + | Setting 4 values for the border radius for a box with a background color + | and a border. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 120px 40px 70px; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border-and-inset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border-and-inset-shadow.html new file mode 100644 index 0000000..b969b0a --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border-and-inset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 4 values for the border radius for a box with a background color, + | a border and an inset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 100px 0px 75px; + box-shadow: 10px 10px #FF7F50 inset; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border-and-outset-shadow.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border-and-outset-shadow.html new file mode 100644 index 0000000..3ec1d92 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border-and-outset-shadow.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + | Setting 4 values for the border radius for a box with a background color, + | a border and an outset shadow. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 100px 0px 75px; + box-shadow: 10px 10px #FF7F50; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border.html b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border.html new file mode 100644 index 0000000..390ecf9 --- /dev/null +++ b/src/cobalt/layout_tests/testdata/css3-background/5-0-border-radius-with-zero-value-and-background-color-and-border.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<!-- + | Setting 4 values for the border radius for a box with a background color + | and a border. + | Note that this will not look the exact same in Chrome since Cobalt + | normalizes opposing corners and Chrome does not. + | https://www.w3.org/TR/css3-background/#border-radius + --> +<html> +<head> + <style> + div { + border: 25px solid rgb(255,192,203); + background-color: rgb(176,176,176); + border-radius: 50px 100px 0px 75px; + height: 200px; + width: 100px; + } + </style> +</head> +<body> + <div></div> +</body> +</html> \ No newline at end of file
diff --git a/src/cobalt/loader/image/image_decoder.cc b/src/cobalt/loader/image/image_decoder.cc index 50f1699..52a5f6a 100644 --- a/src/cobalt/loader/image/image_decoder.cc +++ b/src/cobalt/loader/image/image_decoder.cc
@@ -19,11 +19,7 @@ #include "base/debug/trace_event.h" #include "cobalt/loader/image/dummy_gif_image_decoder.h" #include "cobalt/loader/image/image_decoder_starboard.h" -#if defined(USE_PS3_JPEG_IMAGE_DECODER) -#include "cobalt/loader/image/jpeg_image_decoder_ps3.h" -#else // defined(USE_PS3_JPEG_IMAGE_DECODER) #include "cobalt/loader/image/jpeg_image_decoder.h" -#endif // defined(USE_PS3_JPEG_IMAGE_DECODER) #include "cobalt/loader/image/png_image_decoder.h" #include "cobalt/loader/image/stub_image_decoder.h" #include "cobalt/loader/image/webp_image_decoder.h" @@ -336,13 +332,8 @@ return make_scoped_ptr<ImageDataDecoder>( new StubImageDecoder(resource_provider)); } else if (image_type == ImageDecoder::kImageTypeJPEG) { -#if defined(USE_PS3_JPEG_IMAGE_DECODER) - return make_scoped_ptr<ImageDataDecoder>( - new JPEGImageDecoderPS3(resource_provider)); -#else // defined(USE_PS3_JPEG_IMAGE_DECODER) return make_scoped_ptr<ImageDataDecoder>( new JPEGImageDecoder(resource_provider)); -#endif // defined(USE_PS3_JPEG_IMAGE_DECODER) } else if (image_type == ImageDecoder::kImageTypePNG) { return make_scoped_ptr<ImageDataDecoder>( new PNGImageDecoder(resource_provider));
diff --git a/src/cobalt/loader/loader.gyp b/src/cobalt/loader/loader.gyp index 9a50b4e..1ab0435 100644 --- a/src/cobalt/loader/loader.gyp +++ b/src/cobalt/loader/loader.gyp
@@ -97,12 +97,6 @@ 'embed_resources_as_header_files', ], 'conditions': [ - ['target_arch == "ps3"', { - 'sources': [ - 'image/jpeg_image_decoder_ps3.cc', - 'image/jpeg_image_decoder_ps3.h', - ], - }], ['enable_about_scheme == 1', { 'defines': [ 'ENABLE_ABOUT_SCHEME' ], 'sources': [
diff --git a/src/cobalt/render_tree/rounded_corners.cc b/src/cobalt/render_tree/rounded_corners.cc index 7eacb19..8149cd4 100644 --- a/src/cobalt/render_tree/rounded_corners.cc +++ b/src/cobalt/render_tree/rounded_corners.cc
@@ -29,6 +29,7 @@ } RoundedCorners RoundedCorners::Normalize(const math::RectF& rect) const { + const float kEpsilon = 0.0001f; float scale = 1.0f; float size; @@ -38,27 +39,28 @@ size = top_left.horizontal + std::max(top_right.horizontal, bottom_right.horizontal); if (size > rect.width()) { - scale = rect.width() / size; + scale = (rect.width() - kEpsilon) / size; } size = bottom_left.horizontal + std::max(bottom_right.horizontal, top_right.horizontal); if (size > rect.width()) { - scale = std::min(rect.width() / size, scale); + scale = std::min((rect.width() - kEpsilon) / size, scale); } - size = top_left.vertical + - std::max(bottom_left.vertical, bottom_right.vertical); + size = + top_left.vertical + std::max(bottom_left.vertical, bottom_right.vertical); if (size > rect.height()) { - scale = std::min(rect.height() / size, scale); + scale = std::min((rect.height() - kEpsilon) / size, scale); } size = top_right.vertical + std::max(bottom_right.vertical, bottom_left.vertical); if (size > rect.height()) { - scale = std::min(rect.height() / size, scale); + scale = std::min((rect.height() - kEpsilon) / size, scale); } + scale = std::max(scale, 0.0f); return Scale(scale, scale); }
diff --git a/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc b/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc index 603eb8e..6b7ba0c 100644 --- a/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc +++ b/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc
@@ -640,6 +640,11 @@ backend::GraphicsContextEGL::ScopedMakeCurrent scoped_make_current( graphics_context_, render_target_egl); + // Make sure the render target's framebuffer is bound before continuing. + // Skia will usually do this, but it is possible for some render trees to + // have non-skia draw calls only, in which case this needs to be done. + GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, + render_target_egl->GetPlatformHandle())); // First reset the graphics context state for the pending render tree // draw calls, in case we have modified state in between.
diff --git a/src/starboard/configuration.h b/src/starboard/configuration.h index a8548ea..057bb38 100644 --- a/src/starboard/configuration.h +++ b/src/starboard/configuration.h
@@ -53,7 +53,7 @@ // changes. It is reasonable to base a port on the Release Candidate API // version, but be aware that small incompatible changes may still be made to // it. -#define SB_RELEASE_CANDIDATE_API_VERSION 6 +#define SB_RELEASE_CANDIDATE_API_VERSION 7 // --- Experimental Feature Defines ------------------------------------------
diff --git a/src/starboard/linux/shared/gyp_configuration.py b/src/starboard/linux/shared/gyp_configuration.py index ea8d300..212a904 100644 --- a/src/starboard/linux/shared/gyp_configuration.py +++ b/src/starboard/linux/shared/gyp_configuration.py
@@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All Rights Reserved. +# Copyright 2017 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -80,5 +80,7 @@ test_filter.TestFilter( 'web_platform_tests', 'xhr/WebPlatformTest.Run/125', 'debug'), test_filter.TestFilter( - 'web_platform_tests', 'streams/WebPlatformTest.Run/11', 'debug') + 'web_platform_tests', 'streams/WebPlatformTest.Run/11', 'debug'), + test_filter.TestFilter( + 'starboard_platform_tests', test_filter.FILTER_ALL) ]
diff --git a/src/starboard/linux/x64directfb/__init__.py b/src/starboard/linux/x64directfb/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/starboard/linux/x64directfb/__init__.py
diff --git a/src/starboard/linux/x64directfb/future/gyp_configuration.py b/src/starboard/linux/x64directfb/future/gyp_configuration.py index 1074bc3..446f822 100644 --- a/src/starboard/linux/x64directfb/future/gyp_configuration.py +++ b/src/starboard/linux/x64directfb/future/gyp_configuration.py
@@ -16,7 +16,7 @@ import logging # Import the shared Linux platform configuration. -from starboard.linux.shared import gyp_configuration +import starboard.linux.x64directfb.gyp_configuration as gyp_configuration def CreatePlatformConfig():
diff --git a/src/starboard/linux/x64directfb/gyp_configuration.py b/src/starboard/linux/x64directfb/gyp_configuration.py index 7e60294..483e5dd 100644 --- a/src/starboard/linux/x64directfb/gyp_configuration.py +++ b/src/starboard/linux/x64directfb/gyp_configuration.py
@@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All Rights Reserved. +# Copyright 2017 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,17 +16,45 @@ import logging # Import the shared Linux platform configuration. -from starboard.linux.shared import gyp_configuration +import starboard.linux.shared.gyp_configuration as gyp_configuration +import starboard.tools.testing.test_filter as test_filter def CreatePlatformConfig(): try: - return gyp_configuration.PlatformConfig( - 'linux-x64directfb', - # Unfortunately, some memory leaks outside of our control, and difficult - # to pattern match with ASAN's suppression list, appear in DirectFB - # builds, and so this must be disabled. - asan_enabled_by_default=False) + return PlatformConfig( + 'linux-x64directfb') except RuntimeError as e: logging.critical(e) return None + + +class PlatformConfig(gyp_configuration.PlatformConfig): + + # Unfortunately, some memory leaks outside of our control, and difficult + # to pattern match with ASAN's suppression list, appear in DirectFB + # builds, and so this must be disabled. + def __init__(self, platform, asan_enabled_by_default=False, + goma_supported_by_compiler=True): + super(PlatformConfig, self).__init__( + platform, asan_enabled_by_default, goma_supported_by_compiler) + + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return [ + test_filter.TestFilter( + 'bindings_test', ('GlobalInterfaceBindingsTest.' + 'PropertiesAndOperationsAreOwnProperties')), + test_filter.TestFilter( + 'net_unittests', 'HostResolverImplDnsTest.DnsTaskUnspec'), + test_filter.TestFilter( + 'web_platform_tests', 'xhr/WebPlatformTest.Run/125', 'debug'), + test_filter.TestFilter( + 'web_platform_tests', 'streams/WebPlatformTest.Run/11', 'debug'), + test_filter.TestFilter( + 'starboard_platform_tests', test_filter.FILTER_ALL, 'debug') + ]
diff --git a/src/starboard/linux/x64x11/gyp_configuration.py b/src/starboard/linux/x64x11/gyp_configuration.py index 6685818..9b4962f 100644 --- a/src/starboard/linux/x64x11/gyp_configuration.py +++ b/src/starboard/linux/x64x11/gyp_configuration.py
@@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All Rights Reserved. +# Copyright 2017 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ import logging from starboard.linux.shared import gyp_configuration +import starboard.tools.testing.test_filter as test_filter from starboard.tools.toolchain import ar from starboard.tools.toolchain import bash from starboard.tools.toolchain import clang @@ -49,6 +50,26 @@ bash.Shell(), ] + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return [ + test_filter.TestFilter( + 'bindings_test', ('GlobalInterfaceBindingsTest.' + 'PropertiesAndOperationsAreOwnProperties')), + test_filter.TestFilter( + 'net_unittests', 'HostResolverImplDnsTest.DnsTaskUnspec'), + test_filter.TestFilter( + 'nplb_blitter_pixel_tests', test_filter.FILTER_ALL), + test_filter.TestFilter( + 'web_platform_tests', 'xhr/WebPlatformTest.Run/125', 'debug'), + test_filter.TestFilter( + 'web_platform_tests', 'streams/WebPlatformTest.Run/11', 'debug'), + ] + def CreatePlatformConfig(): try:
diff --git a/src/starboard/linux/x64x11/mock/gyp_configuration.py b/src/starboard/linux/x64x11/mock/gyp_configuration.py index ff41cea..fa14e09 100644 --- a/src/starboard/linux/x64x11/mock/gyp_configuration.py +++ b/src/starboard/linux/x64x11/mock/gyp_configuration.py
@@ -17,7 +17,7 @@ import config.starboard import gyp_utils - +import starboard.tools.testing.test_filter as test_filter def CreatePlatformConfig(): try: @@ -56,3 +56,25 @@ 'CXX': self.host_compiler_environment['CXX_host'], }) return env_variables + + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return [ + test_filter.TestFilter( + 'bindings_test', ('GlobalInterfaceBindingsTest.' + 'PropertiesAndOperationsAreOwnProperties')), + test_filter.TestFilter( + 'net_unittests', 'HostResolverImplDnsTest.DnsTaskUnspec'), + test_filter.TestFilter( + 'nplb_blitter_pixel_tests', test_filter.FILTER_ALL), + test_filter.TestFilter( + 'web_platform_tests', 'xhr/WebPlatformTest.Run/125', 'debug'), + test_filter.TestFilter( + 'web_platform_tests', 'streams/WebPlatformTest.Run/11', 'debug'), + test_filter.TestFilter( + 'starboard_platform_tests', test_filter.FILTER_ALL) + ]
diff --git a/src/starboard/raspi/shared/gyp_configuration.py b/src/starboard/raspi/shared/gyp_configuration.py index f288584..a750f06 100644 --- a/src/starboard/raspi/shared/gyp_configuration.py +++ b/src/starboard/raspi/shared/gyp_configuration.py
@@ -19,6 +19,7 @@ import config.starboard import gyp_utils +import starboard.tools.testing.test_filter as test_filter class RaspiPlatformConfig(config.starboard.PlatformConfigStarboard): @@ -64,3 +65,44 @@ 'CXX': os.path.join(toolchain_bin_dir, 'arm-linux-gnueabihf-g++'), }) return env_variables + + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return [ + # Fails with SpiderMonkey. + test_filter.TestFilter( + 'bindings_test', ('GlobalInterfaceBindingsTest.' + 'PropertiesAndOperationsAreOwnProperties')), + test_filter.TestFilter( + 'net_unittests', 'HostResolverImplDnsTest.DnsTaskUnspec'), + + # The RasPi test devices don't have access to an IPV6 network, so + # disable the related tests. + test_filter.TestFilter( + 'nplb', 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.' + 'SunnyDayDestination/1'), + test_filter.TestFilter( + 'nplb', 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.' + 'SunnyDaySourceForDestination/1'), + test_filter.TestFilter( + 'nplb', 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.' + 'SunnyDaySourceNotLoopback/1'), + + # These tests are currently producing slightly different images on the + # RasPi. + test_filter.TestFilter( + 'renderer_test', 'PixelTest.CircularSubPixelBorder'), + test_filter.TestFilter( + 'renderer_test', 'PixelTest.FilterBlurred100PxText'), + + test_filter.TestFilter('starboard_platform_tests', + test_filter.FILTER_ALL), + test_filter.TestFilter('nplb_blitter_pixel_tests', + test_filter.FILTER_ALL), + test_filter.TestFilter('web_platform_tests', test_filter.FILTER_ALL) + + ]
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc index 7138894..6fd98c6 100644 --- a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc +++ b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.cc
@@ -94,20 +94,8 @@ if (frames_.empty()) { return last_displayed_frame_; } - // Remove any frames with timestamps earlier than |media_time|, but always - // keep at least one of the frames. - while (frames_.size() > 1 && frames_.front()->pts() < media_time) { - if (frames_.front() != last_displayed_frame_) { - ++dropped_frames_; - } - frames_.pop_front(); - } - if (audio_eos_reached) { - while (frames_.size() > 1) { - frames_.pop_back(); - } - } + AdvanceTime(media_time, audio_eos_reached); last_displayed_frame_ = frames_.front(); return last_displayed_frame_; @@ -157,11 +145,30 @@ need_more_input_ = (status == VideoDecoder::kNeedMoreInput); } +void VideoRendererImpl::AdvanceTime( + SbMediaTime media_time, bool audio_eos_reached) { + while (frames_.size() > 1 && frames_.front()->pts() < media_time) { + if (frames_.front() != last_displayed_frame_) { + ++dropped_frames_; + } + frames_.pop_front(); + } + + if (audio_eos_reached) { + while (frames_.size() > 1) { + frames_.pop_back(); + } + } +} + SbDecodeTarget VideoRendererImpl::GetCurrentDecodeTarget( SbMediaTime media_time, bool audio_eos_reached) { - SB_UNREFERENCED_PARAMETER(media_time); - SB_UNREFERENCED_PARAMETER(audio_eos_reached); + { + ScopedLock lock(mutex_); + AdvanceTime(media_time, audio_eos_reached); + } + if (decoder_) { return decoder_->GetCurrentDecodeTarget(); } else {
diff --git a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h index 1dfdad6..675dea8 100644 --- a/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h +++ b/src/starboard/shared/starboard/player/filter/video_renderer_impl_internal.h
@@ -74,6 +74,9 @@ // no longer accept more data. static const size_t kMaxCachedFrames = 12; + // Advances the clock, potentially dropping any expired frames. + void AdvanceTime(SbMediaTime media_time, bool audio_eos_reached); + // VideoDecoder::Host method. void OnDecoderStatusUpdate(VideoDecoder::Status status, const scoped_refptr<VideoFrame>& frame)
diff --git a/src/starboard/shared/uwp/analog_thumbstick_input.cc b/src/starboard/shared/uwp/analog_thumbstick_input.cc new file mode 100644 index 0000000..e4ab130 --- /dev/null +++ b/src/starboard/shared/uwp/analog_thumbstick_input.cc
@@ -0,0 +1,100 @@ +/* + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "starboard/shared/uwp/analog_thumbstick_input.h" + +#include <Windows.Gaming.Input.h> +#include <algorithm> + +#include "starboard/log.h" +#include "starboard/shared/win32/error_utils.h" +#include "starboard/types.h" + +#pragma comment(lib, "xinput9_1_0.lib") + +using Windows::Foundation::Collections::IVectorView; +using Windows::Gaming::Input::Gamepad; +using Windows::Gaming::Input::GamepadReading; +using Windows::Gaming::Input::RawGameController; + +namespace starboard { +namespace shared { +namespace uwp { +namespace { + +const int kMaxPlayerCounter = 4; +const float kDeadZoneThreshold = .24f; + +float ApplyLinearDeadZone(float value, float maxValue, float deadZoneSize) { + if (value < -deadZoneSize) { + // Increase negative values to remove the deadzone discontinuity. + value += deadZoneSize; + } else if (value > deadZoneSize) { + // Decrease positive values to remove the deadzone discontinuity. + value -= deadZoneSize; + } else { + // Values inside the deadzone come out zero. + return 0; + } + + // Scale into 0-1 range. + float scaledValue = value / (maxValue - deadZoneSize); + return std::max(-1.f, std::min(scaledValue, 1.f)); +} + +void ApplyStickDeadZone(float x, + float y, + float max_value, + float dead_zone_size, + float* result_x, + float* result_y) { + *result_x = ApplyLinearDeadZone(x, max_value, dead_zone_size); + *result_y = ApplyLinearDeadZone(y, max_value, dead_zone_size); +} + +ThumbSticks ReadThumbStick(Gamepad ^ controller) { + ThumbSticks output; + GamepadReading reading = controller->GetCurrentReading(); + + ApplyStickDeadZone(static_cast<float>(reading.LeftThumbstickX), + static_cast<float>(reading.LeftThumbstickY), 1.f, + kDeadZoneThreshold, &output.left_x, &output.left_y); + + ApplyStickDeadZone(static_cast<float>(reading.RightThumbstickX), + static_cast<float>(reading.RightThumbstickY), 1.f, + kDeadZoneThreshold, &output.right_x, &output.right_y); + return output; +} +} // namespace + +void GetGamepadThumbSticks(std::vector<ThumbSticks>* destination) { + destination->erase(destination->begin(), destination->end()); + + // This profiled to an average time of 33us to execute. + IVectorView<Gamepad ^> ^ gamepads = Gamepad::Gamepads; + + // This profiled to take on average 9us of time to read controller state. + const uint32_t n = gamepads->Size; + for (uint32_t i = 0; i < n; ++i) { + Gamepad ^ gamepad = gamepads->GetAt(i); + ThumbSticks thumb_stick = ReadThumbStick(gamepad); + destination->push_back(thumb_stick); + } +} + +} // namespace uwp +} // namespace shared +} // namespace starboard
diff --git a/src/starboard/shared/uwp/analog_thumbstick_input.h b/src/starboard/shared/uwp/analog_thumbstick_input.h new file mode 100644 index 0000000..490bc23 --- /dev/null +++ b/src/starboard/shared/uwp/analog_thumbstick_input.h
@@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef STARBOARD_SHARED_UWP_ANALOG_THUMBSTICK_INPUT_H_ +#define STARBOARD_SHARED_UWP_ANALOG_THUMBSTICK_INPUT_H_ + +#include <vector> + +#include "starboard/types.h" + +namespace starboard { +namespace shared { +namespace uwp { + +struct ThumbSticks { + float left_x = 0.0f; + float left_y = 0.0f; + float right_x = 0.0f; + float right_y = 0.0f; +}; + +// Reads all connected game pads and stores the joystick states in the +// destination vector. Note that the destination vector is unconditionally +// cleared before being populated. +void GetGamepadThumbSticks(std::vector<ThumbSticks>* destination); + +} // namespace uwp +} // namespace shared +} // namespace starboard + +#endif // STARBOARD_SHARED_UWP_ANALOG_THUMBSTICK_INPUT_H_
diff --git a/src/starboard/shared/uwp/analog_thumbstick_input_thread.cc b/src/starboard/shared/uwp/analog_thumbstick_input_thread.cc new file mode 100644 index 0000000..6ce605a --- /dev/null +++ b/src/starboard/shared/uwp/analog_thumbstick_input_thread.cc
@@ -0,0 +1,135 @@ +/* + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "starboard/shared/uwp/analog_thumbstick_input_thread.h" + +#include <algorithm> +#include <map> +#include <vector> + +#include "starboard/double.h" +#include "starboard/shared/uwp/analog_thumbstick_input.h" +#include "starboard/shared/win32/simple_thread.h" +#include "starboard/thread.h" + +namespace starboard { +namespace shared { +namespace uwp { + +using starboard::shared::win32::SimpleThread; + +class AnalogThumbstickThread::Impl : public SimpleThread { + public: + explicit Impl(Callback* cb) : SimpleThread("AnalogGamepad"), callback_(cb) { + stick_is_centered_[kSbKeyGamepadLeftStickLeft] = true; + stick_is_centered_[kSbKeyGamepadRightStickLeft] = true; + stick_is_centered_[kSbKeyGamepadLeftStickUp] = true; + stick_is_centered_[kSbKeyGamepadRightStickUp] = true; + + SimpleThread::Start(); + } + ~Impl() { SimpleThread::Join(); } + + void Run() override { + while (!join_called()) { + Update(); + // 120hz to provide smooth 60fps playback. + SbThreadSleep(kSbTimeSecond / kPollingFrequency); + } + } + + void Update() { + ThumbSticks thumb_state = GetCombinedThumbStickState(); + + FireEventIfNecessary(kSbKeyGamepadLeftStickLeft, thumb_state.left_x); + FireEventIfNecessary(kSbKeyGamepadLeftStickUp, thumb_state.left_y); + FireEventIfNecessary(kSbKeyGamepadRightStickLeft, thumb_state.right_x); + FireEventIfNecessary(kSbKeyGamepadRightStickUp, thumb_state.right_y); + } + + void FireEventIfNecessary(SbKey sb_key, float value) { + if (value == 0.0f) { + if (stick_is_centered_[sb_key]) { + // The previous stick input is in center position, so it is not + // necessary to inject another center input event. + return; + } + stick_is_centered_[sb_key] = true; + } else { + stick_is_centered_[sb_key] = false; + } + + SbInputVector input_vector = {0, 0}; + + switch (sb_key) { + case kSbKeyGamepadRightStickLeft: + case kSbKeyGamepadLeftStickLeft: { + input_vector.x = value; + break; + } + case kSbKeyGamepadRightStickUp: + case kSbKeyGamepadLeftStickUp: { + input_vector.y = -value; + break; + } + default: { + SB_NOTREACHED(); + break; + } + } + callback_->OnJoystickUpdate(sb_key, input_vector); + } + + ThumbSticks GetCombinedThumbStickState() { + ThumbSticks all_thumb_state; + GetGamepadThumbSticks(&thumb_sticks_); + + for (int i = 0; i < thumb_sticks_.size(); ++i) { + ThumbSticks thumb_state = thumb_sticks_[i]; + + all_thumb_state.left_x += thumb_state.left_x; + all_thumb_state.left_y += thumb_state.left_y; + all_thumb_state.right_x += thumb_state.right_x; + all_thumb_state.right_y += thumb_state.right_y; + } + + all_thumb_state.left_x = ClampToZeroOne(all_thumb_state.left_x); + all_thumb_state.left_y = ClampToZeroOne(all_thumb_state.left_y); + all_thumb_state.right_x = ClampToZeroOne(all_thumb_state.right_x); + all_thumb_state.right_y = ClampToZeroOne(all_thumb_state.right_y); + + return all_thumb_state; + } + + static float ClampToZeroOne(float in) { + return std::max(-1.0f, std::min(1.0f, in)); + } + Callback* callback_; + std::map<SbKey, bool> stick_is_centered_; + std::vector<ThumbSticks> thumb_sticks_; +}; + +AnalogThumbstickThread::AnalogThumbstickThread(Callback* cb) { + impl_.reset(new Impl(cb)); +} + +AnalogThumbstickThread::~AnalogThumbstickThread() { + impl_.reset(nullptr); +} + +} // namespace uwp +} // namespace shared +} // namespace starboard
diff --git a/src/starboard/shared/uwp/analog_thumbstick_input_thread.h b/src/starboard/shared/uwp/analog_thumbstick_input_thread.h new file mode 100644 index 0000000..e5bbefa --- /dev/null +++ b/src/starboard/shared/uwp/analog_thumbstick_input_thread.h
@@ -0,0 +1,54 @@ +/* + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef STARBOARD_SHARED_UWP_ANALOG_THUMBSTICK_INPUT_THREAD_H_ +#define STARBOARD_SHARED_UWP_ANALOG_THUMBSTICK_INPUT_THREAD_H_ + +#include "starboard/common/scoped_ptr.h" +#include "starboard/configuration.h" +#include "starboard/input.h" + +namespace starboard { +namespace shared { +namespace uwp { + +// This class represents a thread that will poll all gamepads for +// the analog sticks. The sticks are summed together and then +// the callback will be invoked with the thumbstick values. +class AnalogThumbstickThread { + public: + enum { kPollingFrequency = 120 }; // Smooth playback for 60fps. + + class Callback { + public: + virtual ~Callback() {} + virtual void OnJoystickUpdate(SbKey key, SbInputVector position) = 0; + }; + + explicit AnalogThumbstickThread(Callback* cb); + ~AnalogThumbstickThread(); + + private: + SB_DISALLOW_COPY_AND_ASSIGN(AnalogThumbstickThread); + class Impl; + scoped_ptr<Impl> impl_; +}; + +} // namespace uwp +} // namespace shared +} // namespace starboard + +#endif // STARBOARD_SHARED_UWP_ANALOG_THUMBSTICK_INPUT_THREAD_H_
diff --git a/src/starboard/shared/uwp/application_uwp.cc b/src/starboard/shared/uwp/application_uwp.cc index 2343b2a..3609033 100644 --- a/src/starboard/shared/uwp/application_uwp.cc +++ b/src/starboard/shared/uwp/application_uwp.cc
@@ -25,13 +25,16 @@ #include <vector> #include "starboard/event.h" +#include "starboard/input.h" #include "starboard/log.h" #include "starboard/mutex.h" #include "starboard/shared/starboard/application.h" #include "starboard/shared/starboard/audio_sink/audio_sink_internal.h" #include "starboard/shared/starboard/player/video_frame_internal.h" +#include "starboard/shared/uwp/analog_thumbstick_input_thread.h" #include "starboard/shared/uwp/async_utils.h" #include "starboard/shared/uwp/window_internal.h" +#include "starboard/shared/win32/log_file_impl.h" #include "starboard/shared/win32/thread_private.h" #include "starboard/shared/win32/wchar_utils.h" #include "starboard/string.h" @@ -91,9 +94,20 @@ const int kWinSockVersionMinor = 2; const char kDialParamPrefix[] = "cobalt-dial:?"; +const char kLogPathSwitch[] = "xb1_log_file"; int main_return_value = 0; +int MakeDeviceId() { + // TODO: Devices MIGHT have colliding hashcodes. Some other unique int + // ID generation tool would be better. + using Windows::Security::ExchangeActiveSyncProvisioning:: + EasClientDeviceInformation; + auto device_information = ref new EasClientDeviceInformation(); + Platform::String ^ device_id_string = device_information->Id.ToString(); + return device_id_string->GetHashCode(); +} + #if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES) // Parses a starboard: URI scheme by splitting args at ';' boundaries. @@ -149,6 +163,16 @@ return std::equal(substring.rbegin(), substring.rend(), full_string.rbegin()); } +std::string GetBinaryName() { + std::string full_binary_path = GetArgvZero(); + std::string::size_type index = full_binary_path.rfind(SB_FILE_SEP_CHAR); + if (index == std::string::npos) { + return full_binary_path; + } + + return full_binary_path.substr(index + 1); +} + } // namespace // Note that this is a "struct" and not a "class" because @@ -274,7 +298,7 @@ virtual void Uninitialize() { SbAudioSinkPrivate::TearDown(); } void OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) { - SB_DLOG(INFO) << "Suspending"; + SB_DLOG(INFO) << "Suspending application."; // Note if we dispatch "suspend" here before pause, application.cc // will inject the "pause" which will cause us to go async which // will cause us to not have completed the suspend operation before @@ -380,6 +404,17 @@ ApplicationUwp::Get()->SetCommandLine( static_cast<int>(argv_.size()), argv_.data()); } + + ApplicationUwp* application_uwp = ApplicationUwp::Get(); + CommandLine* command_line = + ::starboard::shared::uwp::GetCommandLinePointer(application_uwp); + if (command_line->HasSwitch(kLogPathSwitch)) { + std::string switch_val = command_line->GetSwitchValue(kLogPathSwitch); + sbwin32::OpenLogInCacheDirectory(switch_val.c_str(), + kSbFileCreateAlways); + } + SB_LOG(INFO) << "Starting " << GetBinaryName(); + CoreWindow::GetForCurrentThread()->Activate(); // Call DispatchStart async so the UWP system thinks we're activated. // Some tools seem to want the application to be activated before @@ -456,7 +491,7 @@ // If an argv[0] is required, fill it in with the result of // GetModuleFileName() std::string GetArgvZero() { - const size_t kMaxModuleNameSize = 256; + const size_t kMaxModuleNameSize = SB_FILE_MAX_NAME; wchar_t buffer[kMaxModuleNameSize]; DWORD result = GetModuleFileName(NULL, buffer, kMaxModuleNameSize); std::string arg; @@ -469,9 +504,15 @@ } ApplicationUwp::ApplicationUwp() - : window_(kSbWindowInvalid), localized_strings_(SbSystemGetLocaleId()) {} + : window_(kSbWindowInvalid), + localized_strings_(SbSystemGetLocaleId()), + device_id_(MakeDeviceId()) { + analog_thumbstick_thread_.reset(new AnalogThumbstickThread(this)); +} -ApplicationUwp::~ApplicationUwp() {} +ApplicationUwp::~ApplicationUwp() { + analog_thumbstick_thread_.reset(nullptr); +} void ApplicationUwp::Initialize() {} @@ -595,6 +636,42 @@ SB_NOTIMPLEMENTED(); return 0; } + +void ApplicationUwp::OnJoystickUpdate(SbKey key, SbInputVector input_vector) { + scoped_ptr<SbInputData> data(new SbInputData()); + SbMemorySet(data.get(), 0, sizeof(*data)); + data->window = window_; + data->type = kSbInputEventTypeMove; + data->device_type = kSbInputDeviceTypeGamepad; + data->device_id = device_id(); + data->key = key; + data->character = 0; + + data->key_modifiers = kSbKeyModifiersNone; + data->position = input_vector; + + SbKeyLocation key_location = kSbKeyLocationUnspecified; + switch (key) { + case kSbKeyGamepadLeftStickLeft: + case kSbKeyGamepadLeftStickUp: { + key_location = kSbKeyLocationLeft; + break; + } + case kSbKeyGamepadRightStickLeft: + case kSbKeyGamepadRightStickUp: { + key_location = kSbKeyLocationRight; + } + default: { + SB_NOTREACHED(); + break; + } + } + + data->key_location = key_location; + Inject(new Event(kSbEventTypeInput, data.release(), + &Application::DeleteDestructor<SbInputData>)); +} + SbSystemPlatformError ApplicationUwp::OnSbSystemRaisePlatformError( SbSystemPlatformErrorType type, SbSystemPlatformErrorCallback callback,
diff --git a/src/starboard/shared/uwp/application_uwp.h b/src/starboard/shared/uwp/application_uwp.h index 3ded30a..f961b79 100644 --- a/src/starboard/shared/uwp/application_uwp.h +++ b/src/starboard/shared/uwp/application_uwp.h
@@ -1,145 +1,164 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef STARBOARD_SHARED_UWP_APPLICATION_UWP_H_ -#define STARBOARD_SHARED_UWP_APPLICATION_UWP_H_ - -#include <agile.h> -#include <string> -#include <unordered_map> - -#include "starboard/configuration.h" -#include "starboard/mutex.h" -#include "starboard/shared/internal_only.h" -#include "starboard/shared/starboard/application.h" -#include "starboard/shared/starboard/command_line.h" -#include "starboard/shared/starboard/localized_strings.h" -#include "starboard/types.h" -#include "starboard/window.h" - -namespace starboard { -namespace shared { -namespace uwp { - -using Windows::Media::Protection::HdcpSession; - -// Returns win32's GetModuleFileName(). For cases where we'd like an argv[0]. -std::string GetArgvZero(); - -class ApplicationUwp : public shared::starboard::Application { - public: - ApplicationUwp(); - ~ApplicationUwp() SB_OVERRIDE; - - static ApplicationUwp* Get() { - return static_cast<ApplicationUwp*>(shared::starboard::Application::Get()); - } - - SbWindow CreateWindowForUWP(const SbWindowOptions* options); - - bool DestroyWindow(SbWindow window); - - void DispatchStart() { - shared::starboard::Application::DispatchStart(); - } - - // public for IFrameworkView subclass - void SetCommandLine(int argc, const char** argv) { - shared::starboard::Application::SetCommandLine(argc, argv); - } - - // public for IFrameworkView subclass - bool DispatchAndDelete(Application::Event* event) { - return shared::starboard::Application::DispatchAndDelete(event); - } - - Platform::Agile<Windows::UI::Core::CoreWindow> GetCoreWindow() const { - return core_window_; - } - - // public for IFrameworkView subclass - void SetCoreWindow(Windows::UI::Core::CoreWindow^ window) { - core_window_ = window; - } - - void OnKeyEvent(Windows::UI::Core::CoreWindow^ sender, - Windows::UI::Core::KeyEventArgs^ args, bool up); - - void Inject(Event* event) SB_OVERRIDE; - - void SetStartLink(const char* link) SB_OVERRIDE { - shared::starboard::Application::SetStartLink(link); - } - - SbSystemPlatformError OnSbSystemRaisePlatformError( - SbSystemPlatformErrorType type, - SbSystemPlatformErrorCallback callback, - void* user_data); - - void OnSbSystemClearPlatformError(SbSystemPlatformError handle); - - // Schedules a lambda to run on the main thread and returns immediately. - template<typename T> - void RunInMainThreadAsync(const T& lambda) { - core_window_->Dispatcher->RunAsync( - CoreDispatcherPriority::Normal, - ref new DispatchedHandler(lambda)); - } - - Platform::String^ GetString(const char* id, const char* fallback) const; - - bool IsHdcpOn(); - // Returns true on success. - bool TurnOnHdcp(); - // Returns true on success. - bool TurnOffHdcp(); - - private: - // --- Application overrides --- - bool IsStartImmediate() SB_OVERRIDE { return false; } - void Initialize() SB_OVERRIDE; - void Teardown() SB_OVERRIDE; - Event* GetNextEvent() SB_OVERRIDE; - bool DispatchNextEvent() SB_OVERRIDE; - void InjectTimedEvent(TimedEvent* timed_event) SB_OVERRIDE; - void CancelTimedEvent(SbEventId event_id) SB_OVERRIDE; - TimedEvent* GetNextDueTimedEvent() SB_OVERRIDE; - SbTimeMonotonic GetNextTimedEventTargetTime() SB_OVERRIDE; - - // These two functions should only be called while holding - // |hdcp_session_mutex_|. - Windows::Media::Protection::HdcpSession^ GetHdcpSession(); - void ResetHdcpSession(); - - // The single open window, if any. - SbWindow window_; - Platform::Agile<Windows::UI::Core::CoreWindow> core_window_; - - shared::starboard::LocalizedStrings localized_strings_; - - Mutex mutex_; - // |timer_event_map_| is locked by |mutex_|. - std::unordered_map<SbEventId, Windows::System::Threading::ThreadPoolTimer^> - timer_event_map_; - - // |hdcp_session_| is locked by |hdcp_session_mutex_|. - Mutex hdcp_session_mutex_; - Windows::Media::Protection::HdcpSession^ hdcp_session_; -}; - -} // namespace uwp -} // namespace shared -} // namespace starboard - -#endif // STARBOARD_SHARED_UWP_APPLICATION_UWP_H_ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef STARBOARD_SHARED_UWP_APPLICATION_UWP_H_ +#define STARBOARD_SHARED_UWP_APPLICATION_UWP_H_ + +#include <agile.h> +#include <string> +#include <unordered_map> + +#include "starboard/configuration.h" +#include "starboard/input.h" +#include "starboard/key.h" +#include "starboard/mutex.h" +#include "starboard/shared/internal_only.h" +#include "starboard/shared/starboard/application.h" +#include "starboard/shared/starboard/command_line.h" +#include "starboard/shared/starboard/localized_strings.h" +#include "starboard/shared/uwp/analog_thumbstick_input_thread.h" +#include "starboard/types.h" +#include "starboard/window.h" + +namespace starboard { +namespace shared { +namespace uwp { + +using Windows::Media::Protection::HdcpSession; + +// Returns win32's GetModuleFileName(). For cases where we'd like an argv[0]. +std::string GetArgvZero(); + +// Including <agile.h>, will eventually include <windows.h>, which includes +// C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um\processenv.h, +// line 164 in processenv.h redefines GetCommandLine to GetCommandLineW if +// UNICODE is defined. +// This function was added so that it could be used as a work around when +// GetCommandLine() needed to be called. +starboard::CommandLine* GetCommandLinePointer(starboard::Application* app); + +class ApplicationUwp : public shared::starboard::Application, + private AnalogThumbstickThread::Callback { + public: + ApplicationUwp(); + ~ApplicationUwp() SB_OVERRIDE; + + static ApplicationUwp* Get() { + return static_cast<ApplicationUwp*>(shared::starboard::Application::Get()); + } + + SbWindow CreateWindowForUWP(const SbWindowOptions* options); + + bool DestroyWindow(SbWindow window); + + void DispatchStart() { + shared::starboard::Application::DispatchStart(); + } + + // public for IFrameworkView subclass + void SetCommandLine(int argc, const char** argv) { + shared::starboard::Application::SetCommandLine(argc, argv); + } + + // public for IFrameworkView subclass + bool DispatchAndDelete(Application::Event* event) { + return shared::starboard::Application::DispatchAndDelete(event); + } + + Platform::Agile<Windows::UI::Core::CoreWindow> GetCoreWindow() const { + return core_window_; + } + + // public for IFrameworkView subclass + void SetCoreWindow(Windows::UI::Core::CoreWindow^ window) { + core_window_ = window; + } + + void OnKeyEvent(Windows::UI::Core::CoreWindow^ sender, + Windows::UI::Core::KeyEventArgs^ args, bool up); + + void Inject(Event* event) SB_OVERRIDE; + + void SetStartLink(const char* link) SB_OVERRIDE { + shared::starboard::Application::SetStartLink(link); + } + + SbSystemPlatformError OnSbSystemRaisePlatformError( + SbSystemPlatformErrorType type, + SbSystemPlatformErrorCallback callback, + void* user_data); + + void OnSbSystemClearPlatformError(SbSystemPlatformError handle); + + // Schedules a lambda to run on the main thread and returns immediately. + template<typename T> + void RunInMainThreadAsync(const T& lambda) { + core_window_->Dispatcher->RunAsync( + CoreDispatcherPriority::Normal, + ref new DispatchedHandler(lambda)); + } + + Platform::String^ GetString(const char* id, const char* fallback) const; + + bool IsHdcpOn(); + // Returns true on success. + bool TurnOnHdcp(); + // Returns true on success. + bool TurnOffHdcp(); + + private: + // --- Application overrides --- + bool IsStartImmediate() SB_OVERRIDE { return false; } + void Initialize() SB_OVERRIDE; + void Teardown() SB_OVERRIDE; + Event* GetNextEvent() SB_OVERRIDE; + bool DispatchNextEvent() SB_OVERRIDE; + void InjectTimedEvent(TimedEvent* timed_event) SB_OVERRIDE; + void CancelTimedEvent(SbEventId event_id) SB_OVERRIDE; + TimedEvent* GetNextDueTimedEvent() SB_OVERRIDE; + SbTimeMonotonic GetNextTimedEventTargetTime() SB_OVERRIDE; + + int device_id() const { return device_id_; } + void OnJoystickUpdate(SbKey key, SbInputVector value) SB_OVERRIDE; + + // These two functions should only be called while holding + // |hdcp_session_mutex_|. + Windows::Media::Protection::HdcpSession^ GetHdcpSession(); + void ResetHdcpSession(); + + // The single open window, if any. + SbWindow window_; + Platform::Agile<Windows::UI::Core::CoreWindow> core_window_; + + shared::starboard::LocalizedStrings localized_strings_; + + Mutex mutex_; + // |timer_event_map_| is locked by |mutex_|. + std::unordered_map<SbEventId, Windows::System::Threading::ThreadPoolTimer^> + timer_event_map_; + + int device_id_; + + // |hdcp_session_| is locked by |hdcp_session_mutex_|. + Mutex hdcp_session_mutex_; + Windows::Media::Protection::HdcpSession^ hdcp_session_; + + scoped_ptr<AnalogThumbstickThread> analog_thumbstick_thread_; +}; + +} // namespace uwp +} // namespace shared +} // namespace starboard + +#endif // STARBOARD_SHARED_UWP_APPLICATION_UWP_H_ \ No newline at end of file
diff --git a/src/starboard/shared/uwp/application_uwp_get_commandline_pointer.cc b/src/starboard/shared/uwp/application_uwp_get_commandline_pointer.cc new file mode 100644 index 0000000..669e6a3 --- /dev/null +++ b/src/starboard/shared/uwp/application_uwp_get_commandline_pointer.cc
@@ -0,0 +1,28 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "starboard/shared/starboard/application.h" +#include "starboard/shared/starboard/command_line.h" + +namespace starboard { +namespace shared { +namespace uwp { + +starboard::CommandLine* GetCommandLinePointer(starboard::Application* app) { + return app->GetCommandLine(); +} + +} // namespace uwp +} // namespace shared +} // namespace starboard
diff --git a/src/starboard/shared/uwp/application_uwp_key_event.cc b/src/starboard/shared/uwp/application_uwp_key_event.cc index 73b7d27..cfe7c16 100644 --- a/src/starboard/shared/uwp/application_uwp_key_event.cc +++ b/src/starboard/shared/uwp/application_uwp_key_event.cc
@@ -21,8 +21,6 @@ using Windows::UI::Core::CoreWindow; using Windows::UI::Core::KeyEventArgs; using Windows::UI::Core::CoreVirtualKeyStates; -using Windows::Security::ExchangeActiveSyncProvisioning:: - EasClientDeviceInformation; using Windows::System::VirtualKey; namespace { @@ -255,11 +253,7 @@ data->window = window_; data->device_type = kSbInputDeviceTypeKeyboard; - // TODO: Devices might have colliding hashcodes. Some other unique int - // ID generation tool would be better. - auto device_information = ref new EasClientDeviceInformation(); - Platform::String^ device_id_string = device_information->Id.ToString(); - data->device_id = device_id_string->GetHashCode(); + data->device_id = device_id(); data->key = VirtualKeyToSbKey(args->VirtualKey); if (up) {
diff --git a/src/starboard/shared/uwp/starboard_platform.gypi b/src/starboard/shared/uwp/starboard_platform.gypi index 8d082dc..bb3a5d5 100644 --- a/src/starboard/shared/uwp/starboard_platform.gypi +++ b/src/starboard/shared/uwp/starboard_platform.gypi
@@ -14,7 +14,12 @@ { 'variables': { 'starboard_platform_dependent_files': [ + 'analog_thumbstick_input.cc', + 'analog_thumbstick_input.h', + 'analog_thumbstick_input_thread.cc', + 'analog_thumbstick_input_thread.h', 'application_uwp_key_event.cc', + 'application_uwp_get_commandline_pointer.cc', 'application_uwp.cc', 'application_uwp.h', 'async_utils.h',
diff --git a/src/starboard/shared/win32/gyp_configuration.py b/src/starboard/shared/win32/gyp_configuration.py index 93f92f1..616a9c0 100644 --- a/src/starboard/shared/win32/gyp_configuration.py +++ b/src/starboard/shared/win32/gyp_configuration.py
@@ -18,6 +18,7 @@ import config.starboard from starboard.tools.paths import STARBOARD_ROOT +import starboard.tools.testing.test_filter as test_filter import sdk_configuration @@ -87,3 +88,39 @@ os.path.join(STARBOARD_ROOT, 'shared', 'msvc', 'uwp')) from msvc_toolchain import MSVCUWPToolchain # pylint: disable=g-import-not-at-top,g-bad-import-order return MSVCUWPToolchain() + + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return [ + # Fails on JSC. + test_filter.TestFilter( + 'bindings_test', ('EvaluateScriptTest.ThreeArguments')), + test_filter.TestFilter( + 'bindings_test', ('GarbageCollectionTest.*')), + + test_filter.TestFilter('nplb', test_filter.FILTER_ALL), + test_filter.TestFilter('poem_unittests', test_filter.FILTER_ALL), + + # The Windows platform uses D3D9 which doesn't let you create a D3D + # device without a display, causing these unit tests to erroneously + # fail on the buildbots, so they are disabled for Windows only. + test_filter.TestFilter('layout_tests', test_filter.FILTER_ALL), + test_filter.TestFilter('renderer_test', test_filter.FILTER_ALL), + + # No network on Windows, yet. + test_filter.TestFilter('web_platform_tests', test_filter.FILTER_ALL), + test_filter.TestFilter('net_unittests', test_filter.FILTER_ALL), + + test_filter.TestFilter('starboard_platform_tests', + test_filter.FILTER_ALL), + test_filter.TestFilter('nplb_blitter_pixel_tests', + test_filter.FILTER_ALL), + test_filter.TestFilter('webdriver_test', + test_filter.FILTER_ALL) + + ] +
diff --git a/src/starboard/shared/win32/log_file_impl.cc b/src/starboard/shared/win32/log_file_impl.cc new file mode 100644 index 0000000..1d258ae --- /dev/null +++ b/src/starboard/shared/win32/log_file_impl.cc
@@ -0,0 +1,108 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "starboard/shared/win32/log_file_impl.h" + +#include <string> + +#include "starboard/file.h" +#include "starboard/memory.h" +#include "starboard/mutex.h" +#include "starboard/once.h" +#include "starboard/shared/win32/file_internal.h" +#include "starboard/string.h" + +namespace { + +SbMutex log_mutex = SB_MUTEX_INITIALIZER; +SbFile log_file = kSbFileInvalid; + +} // namespace + +namespace starboard { +namespace shared { +namespace win32 { + +void CloseLogFile() { + SbMutexAcquire(&log_mutex); + + if (SbFileIsValid(log_file)) { + SbFileFlush(log_file); + SbFileClose(log_file); + log_file = kSbFileInvalid; + } + + SbMutexRelease(&log_mutex); +} + +void OpenLogInCacheDirectory(const char* log_file_name, int creation_flags) { + SB_DCHECK((creation_flags & kSbFileOpenAlways) || + (creation_flags & kSbFileCreateAlways)); + SB_DCHECK(SbStringGetLength(log_file_name) != 0); + SB_DCHECK(SbStringFindCharacter(log_file_name, SB_FILE_SEP_CHAR) == nullptr); + char out_path[SB_FILE_MAX_PATH + 1]; + out_path[0] = '\0'; + + if (!SbSystemGetPath(kSbSystemPathCacheDirectory, out_path, + SB_ARRAY_SIZE_INT(out_path))) { + return; + } + + const int path_size = SB_ARRAY_SIZE_INT(out_path); + if (SbStringConcat(out_path, SB_FILE_SEP_STRING, path_size) >= path_size) { + return; + } + if (SbStringConcat(out_path, log_file_name, path_size) >= path_size) { + return; + } + + OpenLogFile(out_path, creation_flags); +} + +void OpenLogFile(const char* path, const int creation_flags) { + SB_DCHECK((creation_flags & kSbFileOpenAlways) || + (creation_flags & kSbFileCreateAlways)); + CloseLogFile(); + SB_DLOG(INFO) << "Logging to [" << path << "]"; + + int flags = creation_flags | kSbFileWrite; + + SbMutexAcquire(&log_mutex); + if ((path != nullptr) && (path != '\0')) { + log_file = SbFileOpen(path, flags, nullptr, nullptr); + SB_DCHECK(SbFileIsValid(log_file)); + } + SbMutexRelease(&log_mutex); +} + +void WriteToLogFile(const char* text, const int text_length) { + if (text_length <= 0) { + return; + } + SbMutexAcquire(&log_mutex); + if (!SbFileIsValid(log_file)) { + SbMutexRelease(&log_mutex); + return; + } + + int bytes_written = SbFileWriteAll(log_file, text, text_length); + SB_DCHECK(text_length == bytes_written); + + SbFileFlush(log_file); + SbMutexRelease(&log_mutex); +} + +} // namespace win32 +} // namespace shared +} // namespace starboard
diff --git a/src/starboard/shared/win32/log_file_impl.h b/src/starboard/shared/win32/log_file_impl.h new file mode 100644 index 0000000..2ed28b9 --- /dev/null +++ b/src/starboard/shared/win32/log_file_impl.h
@@ -0,0 +1,50 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This header provides a mechanism for multiple Android logging +// formats to share a single log file handle. + +#ifndef STARBOARD_SHARED_WIN32_LOG_FILE_IMPL_H_ +#define STARBOARD_SHARED_WIN32_LOG_FILE_IMPL_H_ + +#include "starboard/file.h" +#include "starboard/mutex.h" + +namespace starboard { +namespace shared { +namespace win32 { + +// Closes the log file. +void CloseLogFile(); + +// Opens a file in |kSbSystemPathCacheDirectory| directory. +// |log_file_name|: C-style string of a filename +// |creation_flags|: Must be kSbFileCreateAlways (which will truncate the file) +// |kSbFileOpenAlways|, which can be used to append to the file. +void OpenLogInCacheDirectory(const char* log_file_name, int creation_flags); + +// Opens a file at |log_file_path| with |creation_flags|. +// |log_file_name|: C-style string of a filename +// |creation_flags|: Must be kSbFileCreateAlways (which will truncate the file) +// |kSbFileOpenAlways|, which can be used to append to the file. +void OpenLogFile(const char* log_file_path, int creation_flags); + +// Writes |text_length| bytes starting from |text| to the current log file. +void WriteToLogFile(const char* text, const int text_length); + +} // namespace win32 +} // namespace shared +} // namespace starboard + +#endif // STARBOARD_SHARED_WIN32_LOG_FILE_IMPL_H_
diff --git a/src/starboard/shared/win32/log_raw.cc b/src/starboard/shared/win32/log_raw.cc index d33f086..2929156 100644 --- a/src/starboard/shared/win32/log_raw.cc +++ b/src/starboard/shared/win32/log_raw.cc
@@ -17,7 +17,14 @@ #include <stdio.h> #include <windows.h> +#include "starboard/shared/win32/log_file_impl.h" +#include "starboard/string.h" + +namespace sbwin32 = starboard::shared::win32; + void SbLogRaw(const char* message) { fprintf(stderr, "%s", message); OutputDebugStringA(message); + sbwin32::WriteToLogFile( + message, static_cast<int>(SbStringGetLength(message))); }
diff --git a/src/starboard/shared/win32/log_raw_format.cc b/src/starboard/shared/win32/log_raw_format.cc index 5b6c59e..39b5400 100644 --- a/src/starboard/shared/win32/log_raw_format.cc +++ b/src/starboard/shared/win32/log_raw_format.cc
@@ -17,14 +17,19 @@ #include <stdio.h> #include <windows.h> +#include "starboard/shared/win32/log_file_impl.h" + static const int kMaxLogLineChars = 16 * 1024; +namespace sbwin32 = starboard::shared::win32; + void SbLogRawFormat(const char* format, va_list arguments) { vfprintf(stderr, format, arguments); char log_buffer[kMaxLogLineChars]; int result = vsprintf_s(log_buffer, kMaxLogLineChars, format, arguments); - if (result >= 0) { + if (result > 0) { OutputDebugStringA(log_buffer); + sbwin32::WriteToLogFile(log_buffer, result); } else { OutputDebugStringA("[log line too long]"); }
diff --git a/src/starboard/stub/gyp_configuration.py b/src/starboard/stub/gyp_configuration.py index 63c1c9a..70f8340 100644 --- a/src/starboard/stub/gyp_configuration.py +++ b/src/starboard/stub/gyp_configuration.py
@@ -46,3 +46,11 @@ 'CXX': self.host_compiler_environment['CXX_host'], }) return env_variables + + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return []
diff --git a/src/starboard/tizen/armv7l/gyp_configuration.py b/src/starboard/tizen/armv7l/gyp_configuration.py index 3cee759..50bae01 100644 --- a/src/starboard/tizen/armv7l/gyp_configuration.py +++ b/src/starboard/tizen/armv7l/gyp_configuration.py
@@ -48,3 +48,11 @@ 'CXX_host': 'armv7l-tizen-linux-gnueabi-g++', } return env_variables + + def GetTestFilters(self): + """Gets all tests to be excluded from a unit test run. + + Returns: + A list of initialized TestFilter objects. + """ + return []
diff --git a/src/starboard/win/shared/configuration_public.h b/src/starboard/win/shared/configuration_public.h index 138ca41..44e4ac9 100644 --- a/src/starboard/win/shared/configuration_public.h +++ b/src/starboard/win/shared/configuration_public.h
@@ -20,7 +20,7 @@ // The API version implemented by this platform. This will generally be set to // the current value of SB_MAXIMUM_API_VERSION at the time of implementation. -#define SB_API_VERSION 6 +#define SB_API_VERSION 7 // --- Architecture Configuration --------------------------------------------
diff --git a/src/starboard/win/shared/starboard_platform.gypi b/src/starboard/win/shared/starboard_platform.gypi index ff78819..9302e9c 100644 --- a/src/starboard/win/shared/starboard_platform.gypi +++ b/src/starboard/win/shared/starboard_platform.gypi
@@ -302,6 +302,8 @@ '<(DEPTH)/starboard/shared/win32/file_truncate.cc', '<(DEPTH)/starboard/shared/win32/file_write.cc', '<(DEPTH)/starboard/shared/win32/log.cc', + '<(DEPTH)/starboard/shared/win32/log_file_impl.cc', + '<(DEPTH)/starboard/shared/win32/log_file_impl.h', '<(DEPTH)/starboard/shared/win32/log_flush.cc', '<(DEPTH)/starboard/shared/win32/log_format.cc', '<(DEPTH)/starboard/shared/win32/log_is_tty.cc',