Import Cobalt 9.89162
diff --git a/src/cobalt/browser/stack_size_constants.h b/src/cobalt/browser/stack_size_constants.h index d6b33fc..3d7d7d2 100644 --- a/src/cobalt/browser/stack_size_constants.h +++ b/src/cobalt/browser/stack_size_constants.h
@@ -21,12 +21,12 @@ namespace browser { #if defined(COBALT_BUILD_TYPE_DEBUG) // Non-optimized builds require a bigger stack size. - const size_t kBaseStackSize = 2 * 1024 * 1024; + const size_t kBaseStackSize = 3 * 1024 * 1024; #elif defined(COBALT_BUILD_TYPE_DEVEL) // Devel builds require a slightly bigger stack size. - const size_t kBaseStackSize = 448 * 1024; + const size_t kBaseStackSize = 832 * 1024; #else - const size_t kBaseStackSize = 384 * 1024; + const size_t kBaseStackSize = 768 * 1024; #endif const size_t kWebModuleStackSize = kBaseStackSize + base::kAsanAdditionalStackSize;
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id index 7b38425..1bb91e9 100644 --- a/src/cobalt/build/build.id +++ b/src/cobalt/build/build.id
@@ -1 +1 @@ -76656 \ No newline at end of file +89162 \ No newline at end of file
diff --git a/src/cobalt/css_parser/grammar.y b/src/cobalt/css_parser/grammar.y index 86a9ca0..063c59c 100644 --- a/src/cobalt/css_parser/grammar.y +++ b/src/cobalt/css_parser/grammar.y
@@ -6257,7 +6257,6 @@ std::string property_name = $1.ToString(); DCHECK_GT(property_name.size(), 0U); -#ifdef __LB_SHELL__FORCE_LOGGING__ // Do not warn about non-standard or non-WebKit properties. if (property_name[0] != '-') { base::AutoLock lock(non_trivial_static_fields.Get().lock); @@ -6270,7 +6269,6 @@ parser_impl->LogWarning(@1, "unsupported property " + property_name); } } -#endif // __LB_SHELL__FORCE_LOGGING__ $$ = NULL; }
diff --git a/src/cobalt/css_parser/parser.cc b/src/cobalt/css_parser/parser.cc index 7be1525..086782c 100644 --- a/src/cobalt/css_parser/parser.cc +++ b/src/cobalt/css_parser/parser.cc
@@ -229,7 +229,6 @@ }; // TODO: Stop deduplicating warnings. -#ifdef __LB_SHELL__FORCE_LOGGING__ namespace { struct NonTrivialStaticFields { @@ -242,7 +241,6 @@ LAZY_INSTANCE_INITIALIZER; } // namespace -#endif // __LB_SHELL__FORCE_LOGGING__ ParserImpl::ParserImpl(const std::string& input, const base::SourceLocation& input_location,
diff --git a/src/cobalt/debug/debug_web_server.cc b/src/cobalt/debug/debug_web_server.cc index 76b371f..6ffd152 100644 --- a/src/cobalt/debug/debug_web_server.cc +++ b/src/cobalt/debug/debug_web_server.cc
@@ -80,21 +80,11 @@ return base::nullopt; } -std::string GetLocalIpAddress() { +base::optional<std::string> GetLocalIpAddress() { net::IPEndPoint ip_addr; -#if defined(__LB_SHELL__) - struct sockaddr_in addr = {0}; - addr.sin_family = AF_INET; - lb_get_local_ip_address(&addr.sin_addr); - bool result = - ip_addr.FromSockAddr(reinterpret_cast<sockaddr*>(&addr), sizeof(addr)); - DCHECK(result); -#elif defined(OS_STARBOARD) - -#if SB_API_VERSION >= 4 SbSocketAddress local_ip; - SbMemorySet(&(local_ip.address), 0, sizeof(local_ip.address)); - + SbMemorySet(&local_ip, 0, sizeof(local_ip)); +#if SB_API_VERSION >= 4 bool result = false; // Prefer IPv4 addresses, as they're easier to type for debugging. @@ -115,17 +105,24 @@ } } - DCHECK(result); + if (!result) { + DLOG(WARNING) << "Unable to get a local interface address."; + return base::nullopt; + } #else - SbSocketAddress sb_address; - bool result = SbSocketGetLocalInterfaceAddress(&sb_address); - DCHECK(result); - result = ip_addr.FromSbSocketAddress(&sb_address); + bool result = SbSocketGetLocalInterfaceAddress(&local_ip); + if (!result) { + DLOG(WARNING) << "Unable to get a local interface address."; + return base::nullopt; + } + + result = ip_addr.FromSbSocketAddress(&local_ip); + if (!result) { + LOG(WARNING) << "Got invalid local interface address."; + return base::nullopt; + } #endif // SB_API_VERSION >= 4 -#else -#error "Not Implemented." -#endif return ip_addr.ToStringWithoutPort(); } @@ -339,8 +336,13 @@ DCHECK(thread_checker_.CalledOnValidThread()); // Create http server - const std::string ip_addr = GetLocalIpAddress(); - factory_.reset(new net::TCPListenSocketFactory(ip_addr, port)); + const base::optional<std::string> ip_addr = GetLocalIpAddress(); + if (!ip_addr) { + DLOG(WARNING) + << "Could not get a local IP address for the debug web server."; + return; + } + factory_.reset(new net::TCPListenSocketFactory(*ip_addr, port)); server_ = new net::HttpServer(*factory_, this); std::string address;
diff --git a/src/cobalt/loader/image/animated_webp_image.cc b/src/cobalt/loader/image/animated_webp_image.cc index eef28b9..123d945 100644 --- a/src/cobalt/loader/image/animated_webp_image.cc +++ b/src/cobalt/loader/image/animated_webp_image.cc
@@ -51,7 +51,6 @@ frame_count_(0), loop_count_(kLoopInfinite), current_frame_index_(0), - next_frame_index_(0), should_dispose_previous_frame_to_background_(false), resource_provider_(resource_provider), frame_provider_(new FrameProvider()) { @@ -59,7 +58,7 @@ "AnimatedWebPImage::AnimatedWebPImage()"); } -scoped_refptr<const AnimatedImage::FrameProvider> +scoped_refptr<AnimatedImage::FrameProvider> AnimatedWebPImage::GetFrameProvider() { TRACE_EVENT0("cobalt::loader::image", "AnimatedWebPImage::GetFrameProvider()"); @@ -178,25 +177,25 @@ base::Bind(&AnimatedWebPImage::DecodeFrames, base::Unretained(this))); } - UpdateTimelineInfo(); - - // Decode the frames from current frame to next frame and blend the results. - for (int frame_index = current_frame_index_ + 1; - frame_index <= next_frame_index_; ++frame_index) { - if (!DecodeOneFrame(frame_index)) { - break; - } + if (AdvanceFrame()) { + // Decode the frames from current frame to next frame and blend the results. + DecodeOneFrame(current_frame_index_); } - current_frame_index_ = next_frame_index_; // Set up the next time to call the decode callback. if (is_playing_) { - base::TimeDelta delay = next_frame_time_ - base::TimeTicks::Now(); const base::TimeDelta min_delay = base::TimeDelta::FromMilliseconds(kMinimumDelayInMilliseconds); - if (delay < min_delay) { + base::TimeDelta delay; + if (next_frame_time_) { + delay = *next_frame_time_ - base::TimeTicks::Now(); + if (delay < min_delay) { + delay = min_delay; + } + } else { delay = min_delay; } + message_loop_->PostDelayedTask(FROM_HERE, decode_closure_.callback(), delay); } @@ -294,44 +293,78 @@ return true; } -void AnimatedWebPImage::UpdateTimelineInfo() { - TRACE_EVENT0("cobalt::loader::image", - "AnimatedWebPImage::UpdateTimelineInfo()"); +bool AnimatedWebPImage::AdvanceFrame() { + TRACE_EVENT0("cobalt::loader::image", "AnimatedWebPImage::AdvanceFrame()"); TRACK_MEMORY_SCOPE("Rendering"); DCHECK(message_loop_->BelongsToCurrentThread()); lock_.AssertAcquired(); base::TimeTicks current_time = base::TimeTicks::Now(); - next_frame_index_ = current_frame_index_ ? current_frame_index_ : 1; - while (true) { - // Decode frames, until a frame such that the duration covers the current - // time, i.e. the next frame should be displayed in the future. - WebPIterator webp_iterator; - WebPDemuxGetFrame(demux_, next_frame_index_, &webp_iterator); - next_frame_time_ = current_frame_time_ + base::TimeDelta::FromMilliseconds( - webp_iterator.duration); - WebPDemuxReleaseIterator(&webp_iterator); - if (current_time < next_frame_time_) { - break; + + // If the WebP image hasn't been fully fetched, then stop on the current + // frame. + if (demux_state_ == WEBP_DEMUX_PARSED_HEADER) { + return false; + } + + // If we're done playing the animation, do nothing. + if (LoopingFinished()) { + return false; + } + + // If it's still not time to advance to the next frame, do nothing. + if (next_frame_time_ && current_time < *next_frame_time_) { + return false; + } + + // Always wait for a consumer to consume the previous frame before moving + // forward with decoding the next frame. + if (!frame_provider_->FrameConsumed()) { + return false; + } + + if (next_frame_time_) { + current_frame_time_ = *next_frame_time_; + } else { + current_frame_time_ = current_time; + } + + ++current_frame_index_; + if (current_frame_index_ == frame_count_) { + // Check if we have finished looping, and if so return indicating that there + // is no additional frame available. + if (LoopingFinished()) { + next_frame_time_ = base::nullopt; + return false; } - current_frame_time_ = next_frame_time_; - if (next_frame_index_ < frame_count_) { - next_frame_index_++; - } else { - DCHECK_EQ(next_frame_index_, frame_count_); - // If the WebP image hasn't been fully fetched, or we've reached the end - // of the last loop, then stop on the current frame. - if (demux_state_ == WEBP_DEMUX_PARSED_HEADER || loop_count_ == 1) { - break; - } - next_frame_index_ = 1; - current_frame_index_ = 0; - if (loop_count_ != kLoopInfinite) { - loop_count_--; - } + // Loop around to the beginning + current_frame_index_ = 0; + if (loop_count_ != kLoopInfinite) { + loop_count_--; } } + + // Update the time in the future at which point we should switch to the + // frame after the new current frame. + next_frame_time_ = + current_frame_time_ + GetFrameDuration(current_frame_index_); + if (next_frame_time_ < current_time) { + // Don't let the animation fall back for more than a frame. + next_frame_time_ = current_time; + } + + return true; +} + +base::TimeDelta AnimatedWebPImage::GetFrameDuration(int frame_index) { + lock_.AssertAcquired(); + WebPIterator webp_iterator; + WebPDemuxGetFrame(demux_, frame_index, &webp_iterator); + base::TimeDelta frame_duration = + base::TimeDelta::FromMilliseconds(webp_iterator.duration); + WebPDemuxReleaseIterator(&webp_iterator); + return frame_duration; } scoped_ptr<render_tree::ImageData> AnimatedWebPImage::AllocateImageData( @@ -346,6 +379,10 @@ return image_data.Pass(); } +bool AnimatedWebPImage::LoopingFinished() const { + return loop_count_ == 1 && current_frame_index_ == frame_count_; +} + } // namespace image } // namespace loader } // namespace cobalt
diff --git a/src/cobalt/loader/image/animated_webp_image.h b/src/cobalt/loader/image/animated_webp_image.h index 179d42e..8714c46 100644 --- a/src/cobalt/loader/image/animated_webp_image.h +++ b/src/cobalt/loader/image/animated_webp_image.h
@@ -45,18 +45,21 @@ const math::Size& GetSize() const OVERRIDE { return size_; } uint32 GetEstimatedSizeInBytes() const OVERRIDE { - return static_cast<uint32>(data_buffer_.size()); + // Return the size of 2 frames of images, since we can have two frames in + // memory at a time (the previous decode image passed to the frame provider + // and the next frame that is composed from the previous frame). + return size_.GetArea() * 4 * 2 + static_cast<uint32>(data_buffer_.size()); } bool IsOpaque() const OVERRIDE { return is_opaque_; } - scoped_refptr<const FrameProvider> GetFrameProvider() OVERRIDE; + scoped_refptr<FrameProvider> GetFrameProvider() OVERRIDE; void Play(const scoped_refptr<base::MessageLoopProxy>& message_loop) OVERRIDE; void Stop() OVERRIDE; - void AppendChunk(const uint8* data, size_t size); + void AppendChunk(const uint8* data, size_t input_byte); private: ~AnimatedWebPImage() OVERRIDE; @@ -72,11 +75,17 @@ // Decodes the frame with the given index, returns if it succeeded. bool DecodeOneFrame(int frame_index); - // Updates the index and time info of the current and next frames. - void UpdateTimelineInfo(); - scoped_ptr<render_tree::ImageData> AllocateImageData(const math::Size& size); + // If the time is right, updates the index and time info of the current frame. + bool AdvanceFrame(); + + // Returns the duration of the given frame index. + base::TimeDelta GetFrameDuration(int frame_index); + + // Returns true if the animation loop is finished. + bool LoopingFinished() const; + const math::Size size_; const bool is_opaque_; const render_tree::PixelFormat pixel_format_; @@ -89,7 +98,6 @@ // looping infinitely. int loop_count_; int current_frame_index_; - int next_frame_index_; bool should_dispose_previous_frame_to_background_; render_tree::ResourceProvider* resource_provider_; scoped_refptr<base::MessageLoopProxy> message_loop_; @@ -98,7 +106,7 @@ math::RectF previous_frame_rect_; base::CancelableClosure decode_closure_; base::TimeTicks current_frame_time_; - base::TimeTicks next_frame_time_; + base::optional<base::TimeTicks> next_frame_time_; // The original encoded data. std::vector<uint8> data_buffer_; scoped_refptr<render_tree::Image> current_canvas_;
diff --git a/src/cobalt/loader/image/image.h b/src/cobalt/loader/image/image.h index fe77dac..2b72010 100644 --- a/src/cobalt/loader/image/image.h +++ b/src/cobalt/loader/image/image.h
@@ -88,13 +88,22 @@ // that was in there. class FrameProvider : public base::RefCountedThreadSafe<FrameProvider> { public: + FrameProvider() : frame_consumed_(true) {} + void SetFrame(const scoped_refptr<render_tree::Image>& frame) { base::AutoLock lock(mutex_); frame_ = frame; + frame_consumed_ = false; } - scoped_refptr<render_tree::Image> GetFrame() const { + bool FrameConsumed() const { base::AutoLock lock(mutex_); + return frame_consumed_; + } + + scoped_refptr<render_tree::Image> GetFrame() { + base::AutoLock lock(mutex_); + frame_consumed_ = true; return frame_; } @@ -103,6 +112,9 @@ friend class base::RefCountedThreadSafe<FrameProvider>; mutable base::Lock mutex_; + // True if a call to FrameConsumed() has been made after the last call to + // SetFrame(). + bool frame_consumed_; scoped_refptr<render_tree::Image> frame_; }; @@ -121,11 +133,11 @@ // Returns a FrameProvider object from which frames can be pulled out of. // The AnimatedImage object is expected to push frames into the FrameProvider // as it generates them. - virtual scoped_refptr<const FrameProvider> GetFrameProvider() = 0; + virtual scoped_refptr<FrameProvider> GetFrameProvider() = 0; // This callback is intended to be used in a render_tree::AnimateNode. static void AnimateCallback( - scoped_refptr<const FrameProvider> frame_provider, + scoped_refptr<FrameProvider> frame_provider, const math::RectF& destination_rect, const math::Matrix3F& local_transform, render_tree::ImageNode::Builder* image_node_builder,
diff --git a/src/cobalt/loader/image/image_data_decoder.cc b/src/cobalt/loader/image/image_data_decoder.cc index af95b3b..a7a1920 100644 --- a/src/cobalt/loader/image/image_data_decoder.cc +++ b/src/cobalt/loader/image/image_data_decoder.cc
@@ -67,8 +67,13 @@ } size_t decoded_size = DecodeChunkInternal(input_bytes, input_size); - size_t undecoded_size = input_size - decoded_size; + if (decoded_size == 0 && offset < size) { + LOG(ERROR) << "Unable to make progress decoding image."; + state_ = kError; + return; + } + size_t undecoded_size = input_size - decoded_size; if (undecoded_size == 0) { // Remove all elements from the data_buffer. data_buffer_.clear();
diff --git a/src/cobalt/loader/image/image_decoder_test.cc b/src/cobalt/loader/image/image_decoder_test.cc index 7f995fc..fda87ed 100644 --- a/src/cobalt/loader/image/image_decoder_test.cc +++ b/src/cobalt/loader/image/image_decoder_test.cc
@@ -674,7 +674,7 @@ thread.Stop(); // The image should contain the whole undecoded data from the file. - EXPECT_EQ(3224674u, animated_webp_image->GetEstimatedSizeInBytes()); + EXPECT_EQ(4261474u, animated_webp_image->GetEstimatedSizeInBytes()); EXPECT_EQ(math::Size(480, 270), animated_webp_image->GetSize()); EXPECT_TRUE(animated_webp_image->IsOpaque()); @@ -705,7 +705,7 @@ thread.Stop(); // The image should contain the whole undecoded data from the file. - EXPECT_EQ(3224674u, animated_webp_image->GetEstimatedSizeInBytes()); + EXPECT_EQ(4261474u, animated_webp_image->GetEstimatedSizeInBytes()); EXPECT_EQ(math::Size(480, 270), animated_webp_image->GetSize()); EXPECT_TRUE(animated_webp_image->IsOpaque());
diff --git a/src/cobalt/loader/image/webp_image_decoder.cc b/src/cobalt/loader/image/webp_image_decoder.cc index d587e79..5c803bc 100644 --- a/src/cobalt/loader/image/webp_image_decoder.cc +++ b/src/cobalt/loader/image/webp_image_decoder.cc
@@ -87,8 +87,20 @@ if (status == VP8_STATUS_OK) { DCHECK(image_data()); DCHECK(config_.output.u.RGBA.rgba); - SbMemoryCopy(image_data()->GetMemory(), config_.output.u.RGBA.rgba, - config_.output.u.RGBA.size); + + // Copy the image data over line by line. We copy line by line instead + // of all at once so that we can adjust for differences in pitch between + // source and destination buffers. + uint8* cur_src = config_.output.u.RGBA.rgba; + uint8* cur_dest = image_data()->GetMemory(); + int height = image_data()->GetDescriptor().size.height(); + int num_pixel_bytes = image_data()->GetDescriptor().size.width() * 4; + for (int i = 0; i < height; ++i) { + SbMemoryCopy(cur_dest, cur_src, num_pixel_bytes); + cur_src += config_.output.u.RGBA.stride; + cur_dest += image_data()->GetDescriptor().pitch_in_bytes; + } + set_state(kDone); } else if (status != VP8_STATUS_SUSPENDED) { DLOG(ERROR) << "WebPIAppend error, status code: " << status; @@ -135,10 +147,6 @@ config_.output.colorspace = pixel_format() == render_tree::kPixelFormatRGBA8 ? (has_alpha ? MODE_rgbA : MODE_RGBA) : (has_alpha ? MODE_bgrA : MODE_BGRA); - config_.output.u.RGBA.stride = image_data()->GetDescriptor().pitch_in_bytes; - config_.output.u.RGBA.size = - static_cast<size_t>(config_.output.u.RGBA.stride * - image_data()->GetDescriptor().size.height()); // We don't use image buffer as the decoding buffer because libwebp will read // from it while we assume that our image buffer is write only. config_.output.is_external_memory = 0;
diff --git a/src/cobalt/network/network_module.cc b/src/cobalt/network/network_module.cc index bb4e074..f9fb043 100644 --- a/src/cobalt/network/network_module.cc +++ b/src/cobalt/network/network_module.cc
@@ -122,6 +122,7 @@ base::Thread::Options thread_options; thread_options.message_loop_type = MessageLoop::TYPE_IO; thread_options.stack_size = 256 * 1024; + thread_options.priority = base::kThreadPriority_High; thread_->StartWithOptions(thread_options); base::WaitableEvent creation_event(true, false);
diff --git a/src/cobalt/renderer/backend/egl/graphics_context.cc b/src/cobalt/renderer/backend/egl/graphics_context.cc index 5564bcd..6255fc7 100644 --- a/src/cobalt/renderer/backend/egl/graphics_context.cc +++ b/src/cobalt/renderer/backend/egl/graphics_context.cc
@@ -274,8 +274,13 @@ // with eglMakeCurrent to avoid polluting the previous EGLSurface target. DCHECK_NE(surface->GetPlatformHandle(), 0); - egl_surface = null_surface_->GetSurface(); - EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_)); + // Since we don't care about what surface is backing the default + // framebuffer, don't change draw surfaces unless we simply don't have one + // already. + if (!IsCurrent()) { + egl_surface = null_surface_->GetSurface(); + EGL_CALL(eglMakeCurrent(display_, egl_surface, egl_surface, context_)); + } GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, surface->GetPlatformHandle())); } @@ -289,7 +294,12 @@ } void GraphicsContextEGL::MakeCurrent() { - MakeCurrentWithSurface(null_surface_); + // Some GL drivers do *not* handle switching contexts in the middle of a + // frame very well, so with this change we avoid making a new surface + // current if we don't actually care about what surface is current. + if (!IsCurrent()) { + MakeCurrentWithSurface(null_surface_); + } } void GraphicsContextEGL::ReleaseCurrentContext() {
diff --git a/src/cobalt/renderer/backend/egl/graphics_context.h b/src/cobalt/renderer/backend/egl/graphics_context.h index 49e7c60..ef88e66 100644 --- a/src/cobalt/renderer/backend/egl/graphics_context.h +++ b/src/cobalt/renderer/backend/egl/graphics_context.h
@@ -113,6 +113,9 @@ void Blit(GLuint texture, int x, int y, int width, int height); + // Returns if this graphics context is current on the calling thread or not. + bool IsCurrent() const { return is_current_; } + private: // Performs a test to determine if the pixel data returned by glReadPixels // needs to be vertically flipped or not. This test is expensive, so it
diff --git a/src/cobalt/renderer/rasterizer/blitter/image.cc b/src/cobalt/renderer/rasterizer/blitter/image.cc index f51569e..21a6b1c 100644 --- a/src/cobalt/renderer/rasterizer/blitter/image.cc +++ b/src/cobalt/renderer/rasterizer/blitter/image.cc
@@ -96,7 +96,8 @@ SubmitOffscreenCallback submit_offscreen_callback, SbBlitterDevice device) : size_(static_cast<int>(root->GetBounds().right()), static_cast<int>(root->GetBounds().bottom())), - is_opaque_(false) { + is_opaque_(false), + surface_(kSbBlitterInvalidSurface) { initialize_image_ = base::Bind( &SinglePlaneImage::InitializeImageFromRenderTree, base::Unretained(this), root, submit_offscreen_callback, device);
diff --git a/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc b/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc index 4a95847..3defd2e 100644 --- a/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc +++ b/src/cobalt/renderer/rasterizer/blitter/render_tree_node_visitor.cc
@@ -190,6 +190,11 @@ void RenderTreeNodeVisitor::Visit(render_tree::ImageNode* image_node) { TRACE_EVENT0_IF_ENABLED("Visit(ImageNode)"); + // The image_node may contain nothing. For example, when it represents a video + // or other kind of animated image element before any frame is decoded. + if (!image_node->data().source) { + return; + } // All Blitter API images derive from skia::Image (so that they can be // compatible with the Skia software renderer), so we start here by casting
diff --git a/src/cobalt/renderer/rasterizer/pixel_test.cc b/src/cobalt/renderer/rasterizer/pixel_test.cc index fb95695..192010c 100644 --- a/src/cobalt/renderer/rasterizer/pixel_test.cc +++ b/src/cobalt/renderer/rasterizer/pixel_test.cc
@@ -3405,6 +3405,12 @@ #endif // defined(ENABLE_MAP_TO_MESH) +TEST_F(PixelTest, DrawNullImage) { + // An ImageNode with no source is legal, though it should result in nothing + // being drawn. + TestTree(new ImageNode(NULL, math::RectF(output_surface_size()))); +} + } // namespace rasterizer } // namespace renderer } // namespace cobalt
diff --git a/src/cobalt/renderer/rasterizer/skia/hardware_image.cc b/src/cobalt/renderer/rasterizer/skia/hardware_image.cc index 5eafdd2..6332261 100644 --- a/src/cobalt/renderer/rasterizer/skia/hardware_image.cc +++ b/src/cobalt/renderer/rasterizer/skia/hardware_image.cc
@@ -320,9 +320,16 @@ backend::GraphicsContextEGL* cobalt_context, GrContext* gr_context) { DCHECK_EQ(rasterizer_message_loop_, MessageLoop::current()); + backend::GraphicsContextEGL::ScopedMakeCurrent scoped_make_current( + cobalt_context); + scoped_refptr<backend::FramebufferRenderTargetEGL> render_target( new backend::FramebufferRenderTargetEGL(cobalt_context, size_)); + // The above call to FramebufferRenderTargetEGL() may have dirtied graphics + // state, so tell Skia to reset its context. + gr_context->resetContext(kRenderTarget_GrGLBackendState | + kTextureBinding_GrGLBackendState); submit_offscreen_callback.Run(root, render_target); scoped_ptr<backend::TextureEGL> texture( @@ -330,6 +337,11 @@ backend_image_.reset(new HardwareBackendImage(texture.Pass())); backend_image_->CommonInitialize(gr_context); + + // Tell Skia that the graphics state is unknown because we issued custom + // GL commands above. + gr_context->resetContext(kRenderTarget_GrGLBackendState | + kTextureBinding_GrGLBackendState); } HardwareMultiPlaneImage::HardwareMultiPlaneImage(
diff --git a/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc b/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc index 471f5cd..1af8965 100644 --- a/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc +++ b/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc
@@ -560,6 +560,17 @@ const scoped_refptr<backend::RenderTarget>& render_target) { DCHECK(thread_checker_.CalledOnValidThread()); + scoped_refptr<backend::RenderTargetEGL> render_target_egl( + base::polymorphic_downcast<backend::RenderTargetEGL*>( + render_target.get())); + + if (render_target_egl->is_surface_bad()) { + return; + } + + backend::GraphicsContextEGL::ScopedMakeCurrent scoped_make_current( + graphics_context_, render_target_egl); + // Create a canvas from the render target. GrBackendRenderTargetDesc skia_desc = CobaltRenderTargetToSkiaBackendRenderTargetDesc(render_target.get());
diff --git a/src/cobalt/renderer/rasterizer/testdata/DrawNullImage-expected.png b/src/cobalt/renderer/rasterizer/testdata/DrawNullImage-expected.png new file mode 100644 index 0000000..7f0bfcf --- /dev/null +++ b/src/cobalt/renderer/rasterizer/testdata/DrawNullImage-expected.png Binary files differ
diff --git a/src/cobalt/webdriver_benchmarks/README.md b/src/cobalt/webdriver_benchmarks/README.md deleted file mode 100644 index da77083..0000000 --- a/src/cobalt/webdriver_benchmarks/README.md +++ /dev/null
@@ -1,3 +0,0 @@ -Framework for webdriver-driven benchmarks. - -Please see tests/README.md
diff --git a/src/cobalt/webdriver_benchmarks/__init__.py b/src/cobalt/webdriver_benchmarks/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/src/cobalt/webdriver_benchmarks/__init__.py +++ /dev/null
diff --git a/src/cobalt/webdriver_benchmarks/c_val_names.py b/src/cobalt/webdriver_benchmarks/c_val_names.py deleted file mode 100644 index 6ce4f4d..0000000 --- a/src/cobalt/webdriver_benchmarks/c_val_names.py +++ /dev/null
@@ -1,89 +0,0 @@ -"""Provides cval names needed by the webdriver benchmarks.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - - -def count_dom_active_java_script_events(): - return "Count.DOM.ActiveJavaScriptEvents" - - -def count_dom_html_elements_document(): - return "Count.MainWebModule.DOM.HtmlElement.Document" - - -def count_dom_html_elements_total(): - return "Count.MainWebModule.DOM.HtmlElement.Total" - - -def count_dom_html_script_element_execute(): - return "Count.MainWebModule.DOM.HtmlScriptElement.Execute" - - -def count_layout_boxes(): - return "Count.MainWebModule.Layout.Box" - - -def count_image_cache_loading_resources(): - return "Count.MainWebModule.ImageCache.LoadingResources" - - -def count_image_cache_requested_resources(): - return "Count.MainWebModule.ImageCache.RequestedResources" - - -def count_rasterize_new_render_tree(): - return "Count.Renderer.Rasterize.NewRenderTree" - - -def event_duration_dom_video_start_delay(): - return "Event.Duration.MainWebModule.DOM.VideoStartDelay" - - -def event_is_processing(): - return "Event.MainWebModule.IsProcessing" - - -def event_value_dictionary(event_type): - return "Event.MainWebModule.{}.ValueDictionary".format(event_type) - - -def layout_is_dirty(): - return "MainWebModule.Layout.IsDirty" - - -def rasterize_animations_entry_list(): - return "Renderer.Rasterize.Animations.EntryList" - - -def renderer_has_active_animations(): - return "Renderer.HasActiveAnimations" - - -def time_browser_navigate(): - return "Time.Browser.Navigate" - - -def time_browser_on_load_event(): - return "Time.Browser.OnLoadEvent" - - -def time_cobalt_start(): - return "Time.Cobalt.Start" - - -def time_dom_html_script_element_execute(): - return "Time.MainWebModule.DOM.HtmlScriptElement.Execute" - - -def time_rasterize_animations_start(): - return "Time.Renderer.Rasterize.Animations.Start" - - -def time_rasterize_animations_end(): - return "Time.Renderer.Rasterize.Animations.End" - - -def time_rasterize_new_render_tree(): - return "Time.Renderer.Rasterize.NewRenderTree"
diff --git a/src/cobalt/webdriver_benchmarks/container_util.py b/src/cobalt/webdriver_benchmarks/container_util.py deleted file mode 100644 index 56e948a..0000000 --- a/src/cobalt/webdriver_benchmarks/container_util.py +++ /dev/null
@@ -1,54 +0,0 @@ -"""Base class for WebDriver tests.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import math - - -def mean(list_values): - """Returns the mean of a list of numeric values. - - Args: - list_values: A list of numeric values. - Returns: - Appropriate value. - """ - if not list_values: - return None - - return sum(list_values) / len(list_values) - - -def percentile(list_values, target_percentile): - """Returns the percentile of a list. - - This method interpolates between two numbers if the percentile lands between - two data points. - - Args: - list_values: A sortable list of values - target_percentile: A number ranging from 0-100. - Returns: - Appropriate value. - Raises: - RuntimeError: Raised on invalid args. - """ - if not list_values: - return None - if target_percentile > 100 or target_percentile < 0: - raise RuntimeError("target_percentile must be 0-100") - sorted_values = sorted(list_values) - - if target_percentile == 100: - return sorted_values[-1] - fractional, index = math.modf( - (len(sorted_values) - 1) * (target_percentile * 0.01)) - index = int(index) - - if len(sorted_values) == index + 1: - return sorted_values[index] - - return sorted_values[index] * ( - 1 - fractional) + sorted_values[index + 1] * fractional
diff --git a/src/cobalt/webdriver_benchmarks/container_util_test.py b/src/cobalt/webdriver_benchmarks/container_util_test.py deleted file mode 100755 index 8c29bb4..0000000 --- a/src/cobalt/webdriver_benchmarks/container_util_test.py +++ /dev/null
@@ -1,89 +0,0 @@ -#!/usr/bin/python2 -# Copyright 2016 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. -# ============================================================================== -"""Unit tests for tv_testcase.py.""" -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys -import unittest - -# This directory is a package -sys.path.insert(0, os.path.abspath('.')) -# pylint: disable=C6203,C6203 -# pylint: disable=g-import-not-at-top -import container_util - - -class MeanTest(unittest.TestCase): - - def test_empty_case(self): - self.assertEqual(container_util.mean([]), None) - - def test_one_item(self): - self.assertEqual(container_util.mean([1]), 1) - - def test_two_items(self): - self.assertAlmostEqual(container_util.mean([4, 1]), 2.5) - - def test_three_items(self): - self.assertAlmostEqual(container_util.mean([4, -4, 9]), 3) - - def test_four_items(self): - self.assertAlmostEqual(container_util.mean([6, 0, 1, -2]), 1.25) - - -class MedianPercentileTest(unittest.TestCase): - - def test_empty_case(self): - self.assertEqual(container_util.percentile([], 50), None) - - def test_one_item(self): - self.assertEqual(container_util.percentile([1], 50), 1) - - def test_two_items(self): - self.assertAlmostEqual(container_util.percentile([4, 1], 50), 2.5) - - def test_three_items(self): - self.assertAlmostEqual(container_util.percentile([4, -4, -2], 50), -2) - - def test_four_items(self): - self.assertAlmostEqual(container_util.percentile([4, 0, 1, -2], 50), 0.5) - - -class PercentileTest(unittest.TestCase): - - def test_one_item(self): - self.assertEqual(container_util.percentile([1], 10), 1) - self.assertEqual(container_util.percentile([2], 50), 2) - self.assertEqual(container_util.percentile([3], 90), 3) - - def test_two_items(self): - self.assertEqual(container_util.percentile([2, 1], 10), 1.1) - self.assertEqual(container_util.percentile([2, 3], 50), 2.5) - self.assertEqual(container_util.percentile([3, 4], 90), 3.9) - self.assertEqual(container_util.percentile([3, 4], 100), 4) - - def test_five_items(self): - self.assertEqual(container_util.percentile([2, 1, 3, 4, 5], 10), 1.4) - self.assertEqual(container_util.percentile([2, 1, 3, 4, 5], 50), 3) - self.assertEqual(container_util.percentile([2, 1, 3, 4, 5], 90), 4.6) - self.assertEqual(container_util.percentile([2, 1, 3, 4, 5], 100), 5) - - -if __name__ == '__main__': - sys.exit(unittest.main())
diff --git a/src/cobalt/webdriver_benchmarks/default_query_param_constants.py b/src/cobalt/webdriver_benchmarks/default_query_param_constants.py deleted file mode 100644 index c2347f2..0000000 --- a/src/cobalt/webdriver_benchmarks/default_query_param_constants.py +++ /dev/null
@@ -1,10 +0,0 @@ -"""Default query params to use when loading URLs.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -BASE_QUERY_PARAMS = {} - -INIT_QUERY_PARAMS = {} -INIT_QUERY_PARAMS_TRIGGER_RELOAD = False
diff --git a/src/cobalt/webdriver_benchmarks/tests/README.md b/src/cobalt/webdriver_benchmarks/tests/README.md deleted file mode 100644 index 81fde36..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/README.md +++ /dev/null
@@ -1,292 +0,0 @@ -# Cobalt Webdriver-driven Benchmarks - -This directory contains a set of webdriver-driven benchmarks -for Cobalt. - -Each file should contain a set of tests in Python "unittest" format. - -All tests included within [performance.py](performance.py) will be run on the -build system. Results can be recorded in the build results database. - -## Running the tests - -In most cases, you will want to run all performance tests, and you can do so by -executing the script [performance.py](performance.py). You can call -`python performance.py --help` to see a list of commandline parameters to call -it with. For example, to run tests on the raspi-2 QA build, you should run the -following command: - -``` -python performance.py -p raspi-2 -c qa -d $RASPI_ADDR -``` - -Where `RASPI_ADDR` is set to the IP of the target Raspberry Pi device. - -To run individual tests, simply execute the script directly. For all tests, -platform configuration will be inferred from the environment if set. Otherwise, -it must be specified via commandline parameters. - -## Creating a new test - - 1. If appropriate, create a new file borrowing the boilerplate from - an existing simple file, such as - [browse_horizontal.py](performance/non_video/browse_horizontal.py). - - 2. Add the file name to the tests added within - [performance.py](performance.py), causing it run when - [performance](performance.py) is run. - - 3. If this file contains internal names or details, consider adding it - to the "EXCLUDE.FILES" list. - - 4. Use the `record_test_result*` methods in `tv_testcase_util` where - appropriate. - - 5. Results must be added to the build results database schema. See - the internal - [README-Updating-Result-Schema.md](README-Updating-Result-Schema.md) file. - -## Testing against specific loaders/labels - -To run the benchmarks against any desired loader, a --url command line parameter -can be provided. This will be the url that the tests will run against. - -It should have the following format: - -``` -python performance.py -p raspi-2 -c qa -d $RASPI_ADDR --url https://www.youtube.com/tv?loader=nllive -``` - -## Benchmark Results - -The results will be printed to stdout. You should redirect output to a file -if you would like to store the results. Each line of the benchmark output -prefixed with `webdriver_benchmark TEST_RESULT:` provides the result of one -measurment. Those lines have the following format: - -``` -webdriver_benchmark TEST_RESULT: result_name result_value -``` - -where `result_name` is the name of the result and `result_value` is a number -providing the measured result for that metric. For example, - -``` -webdriver_benchmark TEST RESULT: wbBrowseHorizontalDurLayoutBoxTreeUpdateUsedSizesUsPct50 3061.5 -``` - -gives the 50th percentile of the duration Cobalt took to update the box tree's -used sizes, on a horizontal scroll event, in microseconds. - -Note that most time-based measurements are in microseconds. - -### Interesting Timing-Related Benchmarks -Some particularly interesting timing-related benchmark results are: - -#### Startup - - `wbStartupDurLaunchToBrowseUs`: Measures the time it takes to launch Cobalt - and load the desired URL. The measurement ends when all images finish loading - and the final render tree is produced. This is only run once so it will be - noiser than other values but provides the most accurate measurement of the - requirement startup time. - - `wbStartupDurLaunchToUsableUs`: Measures the time it takes to launch Cobalt, - and fully load the desired URL, including loading all scripts. The - measurement ends when the Player JavaScript code finishes loading on the - Browse page, which is the point when Cobalt is fully usable. This is only run - once so it will be noiser than other values but provides the most accurate - measurement of the time when Cobalt is usable. - - `wbStartupDurNavigateToBrowseUs*`: Measures the time it takes to navigate to - the desired URL when Cobalt is already loaded. The measurement ends when all - images finish loading and the final render tree is produced. This is run - multiple times, so it will be less noisy than `wbStartupDurLaunchToBrowseUs`, - but it does not include Cobalt initialization so it is not as accurate of a - measurement. - - `wbStartupDurNavigateToUsableUs`: Measures the time it takes to navigate to - the desired URL when Cobalt is already loaded, including loading all scripts. - The measurement ends when the Player JavaScript code finishes loading on the - Browse page, which is the point when Cobalt is fully usable. This is run - multiple times, so it will be less noisy than `wbStartupDurLaunchToUsableUs`, - but it does not include Cobalt initialization so it is not as accurate of a - measurement. - -#### Browse Horizontal Scroll Events - - `wbBrowseHorizontalDurTotalUs*`: Measures the latency (i.e. JavaScript - execution time + layout time) during horizontal scroll events from keypress - until the render tree is submitted to the rasterize thread. It does not - include the time taken to rasterize the render tree so it will be smaller - than the observed latency. - - `wbBrowseHorizontalDurAnimationsStartDelayUs*`: Measures the input latency - during horizontal scroll events from the keypress until the animation starts. - This is the most accurate measure of input latency. - - `wbBrowseHorizontalDurAnimationsEndDelayUs*`: Measures the latency during - horizontal scroll events from the keypress until the animation ends. - - `wbBrowseHorizontalDurFinalRenderTreeDelayUs*`: Measures the latency during - horizontal scroll events from the keypress until the final render tree is - rendered and processing stops. - - `wbBrowseHorizontalDurRasterizeAnimationsUs*`: Measures the time it takes to - render each frame of the animation triggered by a horizontal scroll event. - The inverse of this number is the framerate. - -#### Browse Vertical Scroll Events - - `wbBrowseVerticalDurTotalUs*`: Measures the latency (i.e. JavaScript - execution time + layout time) during vertical scroll events from keypress - until the render tree is submitted to the rasterize thread. It does not - include the time taken to rasterize the render tree so it will be smaller - than the observed latency. - - `wbBrowseVerticalDurAnimationsStartDelayUs*`: Measures the input latency - during vertical scroll events from the keypress until the animation starts. - This is the most accurate measure of input latency. - - `wbBrowseVerticalDurAnimationsEndDelayUs*`: Measures the latency during - vertical scroll events from the keypress until the animation ends. - - `wbBrowseVerticalDurFinalRenderTreeDelayUs*`: Measures the latency during - vertical scroll events from the keypress until the final render tree is - rendered and processing stops. - - `wbBrowseVerticalDurRasterizeAnimationsUs*`: Measures the time it takes to - render each frame of the animation triggered by a vertical scroll event. - The inverse of this number is the framerate. - -#### Browse-to-Watch - - `wbBrowseToWatchDurVideoStartDelay*`: Measures the browse-to-watch time. - -In each case above, the `*` symbol can be one of either `Mean`, `Pct25`, -`Pct50`, `Pct75` or `Pct95`. For example, `wbStartupDurBlankToBrowseUsMean` or -`wbStartupDurBlankToBrowseUsPct95` are both valid measurements. The webdriver -benchmarks runs its tests many times in order to obtain multiple samples, so you -can drill into the data by exploring either the mean, or the various -percentiles. - -### Interesting Count-Related Benchmarks -Some particularly interesting count-related benchmark results are: - -#### Startup - - `wbStartupCntDomHtmlElements*`: Lists the number of HTML elements in - existence after startup completes. This includes HTML elements that are no - longer in the DOM but have not been garbage collected yet. - - `wbStartupCntDocumentDomHtmlElements*`: Lists the number of HTML - elements within the DOM tree after startup completes. - - `wbStartupCntLayoutBoxes*`: Lists the number of layout boxes within - the layout tree after startup completes. - - `wbStartupCntRenderTrees*`: Lists the number of render trees that were - generated during startup. - - `wbStartupCntRequestedImages*`: Lists the number of images that were - requested during startup. - -#### Browse Horizontal Scroll Events - - `wbBrowseHorizontalCntDomHtmlElements*`: Lists the number of HTML elements in - existence after the event. This includes HTML elements that are no longer in - the DOM but have not been garbage collected yet. - - `wbBrowseHorizontalCntDocumentDomHtmlElements*`: Lists the number of HTML - elements within the DOM tree after the event. - - `wbBrowseHorizontalCntLayoutBoxes*`: Lists the number of layout boxes within - the layout tree after the event. - - `wbBrowseHorizontalCntLayoutBoxesCreated*`: Lists the number of new layout - boxes that were created during the event. - - `wbBrowseHorizontalCntRenderTrees*`: Lists the number of render trees that - were generated by the event. - - `wbBrowseHorizontalCntRequestedImages*`: Lists the number of images that were - requested as a result of the event. - -#### Browse Vertical Scroll Events - - `wbBrowseVerticalCntDomHtmlElements*`: Lists the number of HTML elements in - existence after the event. This includes HTML elements that are no longer in - the DOM but have not been garbage collected yet. - - `wbBrowseVerticalCntDocumentDomHtmlElements*`: Lists the number of HTML - elements within the DOM tree after the event. - - `wbBrowseVerticalCntLayoutBoxes*`: Lists the number of layout boxes within - the layout tree after the event. - - `wbBrowseVerticalCntLayoutBoxesCreated*`: Lists the number of new layout - boxes that were created during the event. - - `wbBrowseVerticalCntRenderTrees*`: Lists the number of render trees that - were generated by the event. - - `wbBrowseVerticalCntRequestedImages*`: Lists the number of images that were - requested as a result of the event. - -In each case above, the `*` symbol can be one of either `Max`, `Median`, or -`Mean`. For example, `wbBrowseVerticalCntDomHtmlElementsMax` or -`wbBrowseVerticalCntDomHtmlElementsMedian` are both valid measurements. The -webdriver benchmarks runs its tests many times in order to obtain multiple -samples, so you can drill into the data by exploring either the max, median, or -mean. - -### Filtering results - -The webdriver benchmarks output many metrics, but you may only be interested -in a few. You will have to manually filter only the metrics that you are -interested in. You can do so with `grep`, for example: - -``` -python performance.py -p raspi-2 -c qa -d $RASPI_ADDR > results.txt -echo "" > filtered_results.txt -printf "=================================TIMING-RELATED=================================\n" >> filtered_results.txt -printf "\nSTARTUP\n" >> filtered_results.txt -grep -o "wbStartupDurLaunchToBrowseUs.*$" results.txt >> filtered_results.txt -grep -o "wbStartupDurLaunchToUsableUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbStartupDurNavigateToBrowseUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbStartupDurNavigateToUsableUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -printf "\nBROWSE HORIZONTAL SCROLL EVENTS\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalDurTotalUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalDurAnimationsStartDelayUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalDurAnimationsEndDelayUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalDurFinalRenderTreeDelayUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalDurRasterizeAnimationsUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -printf "\nBROWSE VERTICAL SCROLL EVENTS\n" >> filtered_results.txt -grep -o "wbBrowseVerticalDurTotalUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalDurAnimationsStartDelayUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalDurAnimationsEndDelayUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalDurFinalRenderTreeDelayUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalDurRasterizeAnimationsUs.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -printf "\nBROWSE TO WATCH\n" >> filtered_results.txt -grep -o "wbBrowseToWatchDurVideoStartDelay.*$" results.txt >> filtered_results.txt -printf "\n\n=================================COUNT-RELATED==================================\n" >> filtered_results.txt -printf "\nSTARTUP\n" >> filtered_results.txt -grep -o "wbStartupCntDomHtmlElements.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbStartupCntDomDocumentHtmlElements.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbStartupCntLayoutBoxes.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbStartupCntRenderTrees.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbStartupCntRequestedImages.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -printf "\nBROWSE HORIZONTAL SCROLL EVENTS\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalCntDomHtmlElementsM.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalCntDomDocumentHtmlElements.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalCntLayoutBoxesM.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalCntLayoutBoxesCreated.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalCntRenderTrees.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseHorizontalCntRequestedImages.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -printf "\nBROWSE VERTICAL SCROLL EVENTS\n" >> filtered_results.txt -grep -o "wbBrowseVerticalCntDomHtmlElementsM.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalCntDomDocumentHtmlElements.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalCntLayoutBoxesM.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalCntLayoutBoxesCreated.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalCntRenderTrees.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -grep -o "wbBrowseVerticalCntRequestedImages.*$" results.txt >> filtered_results.txt -printf "\n" >> filtered_results.txt -cat filtered_results.txt -```
diff --git a/src/cobalt/webdriver_benchmarks/tests/__init__.py b/src/cobalt/webdriver_benchmarks/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/__init__.py +++ /dev/null
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance.py b/src/cobalt/webdriver_benchmarks/tests/performance.py deleted file mode 100644 index 8495f71..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance.py +++ /dev/null
@@ -1,40 +0,0 @@ -#!/usr/bin/python2 -"""Target for running all performance test cases.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import importlib -import os -import sys -import unittest - -# The parent directory is a module -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) - -# pylint: disable=C6204,C6203 -import tv_testcase - - -def _add_test(test_suite, dir_path, test_name): - if os.path.isfile(os.path.join(dir_path, test_name + ".py")): - print("Adding test: {}".format(test_name)) - test_suite.addTest(unittest.TestLoader().loadTestsFromModule( - importlib.import_module("tests." + test_name))) - - -# pylint: disable=unused-argument -def load_tests(loader, tests, pattern): - """This is a Python unittest "load_tests protocol method.""" - test_suite = unittest.TestSuite() - dir_path = os.path.dirname(__file__) - - _add_test(test_suite, dir_path, "performance_non_video") - _add_test(test_suite, dir_path, "performance_video") - - return test_suite - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/__init__.py b/src/cobalt/webdriver_benchmarks/tests/performance/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/__init__.py +++ /dev/null
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/__init__.py b/src/cobalt/webdriver_benchmarks/tests/performance/non_video/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/__init__.py +++ /dev/null
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_horizontal.py b/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_horizontal.py deleted file mode 100755 index 2da83c6..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_horizontal.py +++ /dev/null
@@ -1,54 +0,0 @@ -#!/usr/bin/python2 -"""Simple benchmark of horizontally navigating shelves during browse.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys - -# Add the base webdriver_benchmarks path -sys.path.insert(0, - os.path.dirname( - os.path.dirname((os.path.dirname( - os.path.dirname(os.path.realpath(__file__))))))) - -# pylint: disable=C6204,C6203 -import tv_testcase -import tv_testcase_event_recorder -import tv_testcase_util - -# selenium imports -keys = tv_testcase_util.import_selenium_module("webdriver.common.keys") - -NUM_LOAD_TV_CALLS = 5 -NUM_ITERATIONS_PER_LOAD_TV_CALL = 20 - -BROWSE_HORIZONTAL_EVENT_NAME = "wbBrowseHorizontal" -BROWSE_HORIZONTAL_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_DOWN - - -class BrowseHorizontalTest(tv_testcase.TvTestCase): - - def test_simple(self): - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, BROWSE_HORIZONTAL_EVENT_NAME, BROWSE_HORIZONTAL_EVENT_TYPE) - recorder = tv_testcase_event_recorder.EventRecorder(recorder_options) - - for _ in xrange(NUM_LOAD_TV_CALLS): - self.load_tv() - self.send_keys(keys.Keys.ARROW_RIGHT) - self.wait_for_processing_complete_after_focused_shelf() - - for _ in xrange(NUM_ITERATIONS_PER_LOAD_TV_CALL): - recorder.on_start_event() - self.send_keys(keys.Keys.ARROW_RIGHT) - self.wait_for_processing_complete_after_focused_shelf() - recorder.on_end_event() - - recorder.on_end_test() - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_to_guide.py b/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_to_guide.py deleted file mode 100755 index 7e5230f..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_to_guide.py +++ /dev/null
@@ -1,69 +0,0 @@ -#!/usr/bin/python2 -"""Simple benchmark for going from browse to guide and back.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys - -# Add the base webdriver_benchmarks path -sys.path.insert(0, - os.path.dirname( - os.path.dirname((os.path.dirname( - os.path.dirname(os.path.realpath(__file__))))))) - -# pylint: disable=C6204,C6203 -import tv -import tv_testcase -import tv_testcase_event_recorder -import tv_testcase_util - -# selenium imports -keys = tv_testcase_util.import_selenium_module("webdriver.common.keys") - -NUM_LOAD_TV_CALLS = 1 -NUM_ITERATIONS_PER_LOAD_TV_CALL = 20 - -BROWSE_TO_GUIDE_EVENT_NAME = "wbBrowseToGuide" -BROWSE_TO_GUIDE_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_DOWN - -GUIDE_TO_BROWSE_EVENT_NAME = "wbGuideToBrowse" -GUIDE_TO_BROWSE_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_DOWN - - -class BrowseToGuideTest(tv_testcase.TvTestCase): - - def test_simple(self): - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, BROWSE_TO_GUIDE_EVENT_NAME, BROWSE_TO_GUIDE_EVENT_TYPE) - browse_to_guide_recorder = tv_testcase_event_recorder.EventRecorder( - recorder_options) - - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, GUIDE_TO_BROWSE_EVENT_NAME, GUIDE_TO_BROWSE_EVENT_TYPE) - guide_to_browse_recorder = tv_testcase_event_recorder.EventRecorder( - recorder_options) - - for _ in xrange(NUM_LOAD_TV_CALLS): - self.load_tv() - - for _ in xrange(NUM_ITERATIONS_PER_LOAD_TV_CALL): - browse_to_guide_recorder.on_start_event() - self.send_keys(keys.Keys.ARROW_LEFT) - self.wait_for_processing_complete() - self.assert_displayed(tv.FOCUSED_GUIDE) - browse_to_guide_recorder.on_end_event() - - guide_to_browse_recorder.on_start_event() - self.send_keys(keys.Keys.ARROW_RIGHT) - self.wait_for_processing_complete_after_focused_shelf() - guide_to_browse_recorder.on_end_event() - - browse_to_guide_recorder.on_end_test() - guide_to_browse_recorder.on_end_test() - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_to_search.py b/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_to_search.py deleted file mode 100755 index a2d82de..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_to_search.py +++ /dev/null
@@ -1,71 +0,0 @@ -#!/usr/bin/python2 -"""Simple benchmark for going from browse to search and back.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys - -# Add the base webdriver_benchmarks path -sys.path.insert(0, - os.path.dirname( - os.path.dirname((os.path.dirname( - os.path.dirname(os.path.realpath(__file__))))))) - -# pylint: disable=C6204,C6203 -import tv -import tv_testcase -import tv_testcase_event_recorder -import tv_testcase_util - -# selenium imports -keys = tv_testcase_util.import_selenium_module("webdriver.common.keys") - -NUM_LOAD_TV_CALLS = 1 -NUM_ITERATIONS_PER_LOAD_TV_CALL = 20 - -BROWSE_TO_SEARCH_EVENT_NAME = "wbBrowseToSearch" -BROWSE_TO_SEARCH_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_UP - -SEARCH_TO_BROWSE_EVENT_NAME = "wbSearchToBrowse" -SEARCH_TO_BROWSE_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_UP - - -class BrowseToSearchTest(tv_testcase.TvTestCase): - - def test_simple(self): - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, BROWSE_TO_SEARCH_EVENT_NAME, BROWSE_TO_SEARCH_EVENT_TYPE) - recorder_options.record_animations = False - browse_to_search_recorder = tv_testcase_event_recorder.EventRecorder( - recorder_options) - - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, SEARCH_TO_BROWSE_EVENT_NAME, SEARCH_TO_BROWSE_EVENT_TYPE) - recorder_options.record_animations = False - search_to_browse_recorder = tv_testcase_event_recorder.EventRecorder( - recorder_options) - - for _ in xrange(NUM_LOAD_TV_CALLS): - self.load_tv() - - for _ in xrange(NUM_ITERATIONS_PER_LOAD_TV_CALL): - browse_to_search_recorder.on_start_event() - self.send_keys("s") - self.wait_for_processing_complete(False) - self.assert_displayed(tv.FOCUSED_SEARCH) - browse_to_search_recorder.on_end_event() - - search_to_browse_recorder.on_start_event() - self.send_keys(keys.Keys.ESCAPE) - self.wait_for_processing_complete_after_focused_shelf() - search_to_browse_recorder.on_end_event() - - browse_to_search_recorder.on_end_test() - search_to_browse_recorder.on_end_test() - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_vertical.py b/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_vertical.py deleted file mode 100755 index 08a687e..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/browse_vertical.py +++ /dev/null
@@ -1,54 +0,0 @@ -#!/usr/bin/python2 -"""Simple benchmark of vertically navigating shelves during browse.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys - -# Add the base webdriver_benchmarks path -sys.path.insert(0, - os.path.dirname( - os.path.dirname((os.path.dirname( - os.path.dirname(os.path.realpath(__file__))))))) - -# pylint: disable=C6204,C6203 -import tv_testcase -import tv_testcase_event_recorder -import tv_testcase_util - -# selenium imports -keys = tv_testcase_util.import_selenium_module("webdriver.common.keys") - -NUM_LOAD_TV_CALLS = 4 -NUM_ITERATIONS_PER_LOAD_TV_CALL = 25 - -BROWSE_VERTICAL_EVENT_NAME = "wbBrowseVertical" -BROWSE_VERTICAL_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_DOWN - - -class BrowseVerticalTest(tv_testcase.TvTestCase): - - def test_simple(self): - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, BROWSE_VERTICAL_EVENT_NAME, BROWSE_VERTICAL_EVENT_TYPE) - recorder = tv_testcase_event_recorder.EventRecorder(recorder_options) - - for _ in xrange(NUM_LOAD_TV_CALLS): - self.load_tv() - self.send_keys(keys.Keys.ARROW_DOWN) - self.wait_for_processing_complete_after_focused_shelf() - - for _ in xrange(NUM_ITERATIONS_PER_LOAD_TV_CALL): - recorder.on_start_event() - self.send_keys(keys.Keys.ARROW_DOWN) - self.wait_for_processing_complete_after_focused_shelf() - recorder.on_end_event() - - recorder.on_end_test() - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/startup.py b/src/cobalt/webdriver_benchmarks/tests/performance/non_video/startup.py deleted file mode 100755 index c37008e..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/non_video/startup.py +++ /dev/null
@@ -1,164 +0,0 @@ -#!/usr/bin/python2 -"""Simple benchmark for measuring startup time.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys - -# Add the base webdriver_benchmarks path -sys.path.insert(0, - os.path.dirname( - os.path.dirname((os.path.dirname( - os.path.dirname(os.path.realpath(__file__))))))) - -# pylint: disable=C6204,C6203 -import c_val_names -import tv_testcase -import tv_testcase_util - -NUM_LOAD_TV_ITERATIONS = 20 - -STARTUP_RECORD_NAME = "wbStartup" - - -class StartupTest(tv_testcase.TvTestCase): - - def setUp(self): - # Override TvTestCase's setUp() so that blank startup can first be measured. - pass - - def test_simple(self): - """This test tries to measure the startup time for the YouTube TV page.""" - self.wait_for_processing_complete() - self.wait_for_html_script_element_execute_count(2) - - # Measure durations for the intial launch. - launch_time = self.get_cval(c_val_names.time_cobalt_start()) - navigate_time = self.get_cval(c_val_names.time_browser_navigate()) - on_load_event_time = self.get_cval(c_val_names.time_browser_on_load_event()) - browse_time = self.get_cval(c_val_names.time_rasterize_new_render_tree()) - usable_time = self.get_cval( - c_val_names.time_dom_html_script_element_execute()) - - dur_launch_to_navigate_us = navigate_time - launch_time - dur_launch_to_on_load_event_us = on_load_event_time - launch_time - dur_launch_to_browse_us = browse_time - launch_time - dur_launch_to_usable_us = usable_time - launch_time - - # Call TvTestCase's setUp() now that the launch times have been measured. - super(StartupTest, self).setUp() - - # Count record strategies - count_record_strategies = [] - count_record_strategies.append(tv_testcase_util.RecordStrategyMean()) - count_record_strategies.append(tv_testcase_util.RecordStrategyMin()) - count_record_strategies.append(tv_testcase_util.RecordStrategyMedian()) - count_record_strategies.append(tv_testcase_util.RecordStrategyMax()) - - # Duration record strategies - duration_record_strategies = [] - duration_record_strategies.append(tv_testcase_util.RecordStrategyMean()) - duration_record_strategies.append(tv_testcase_util.RecordStrategyMin()) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(25)) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(50)) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(75)) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(95)) - duration_record_strategies.append(tv_testcase_util.RecordStrategyMax()) - - # Count recorders - count_total_html_element_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "CntDomHtmlElements", count_record_strategies) - count_document_html_element_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "CntDomDocumentHtmlElements", - count_record_strategies) - count_layout_box_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "CntLayoutBoxes", count_record_strategies) - count_render_trees_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "CntRenderTrees", count_record_strategies) - count_requested_images_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "CntRequestedImages", count_record_strategies) - - # Duration recorders - duration_navigate_to_on_load_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "DurNavigateToOnLoadUs", - duration_record_strategies) - duration_navigate_to_browse_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "DurNavigateToBrowseUs", - duration_record_strategies) - duration_navigate_to_usable_recorder = tv_testcase_util.ResultsRecorder( - STARTUP_RECORD_NAME + "DurNavigateToUsableUs", - duration_record_strategies) - - # Now measure counts and durations from reloading the URL. - for _ in range(NUM_LOAD_TV_ITERATIONS): - count_render_trees_start = self.get_cval( - c_val_names.count_rasterize_new_render_tree()) - - self.load_tv() - - count_render_trees_end = self.get_cval( - c_val_names.count_rasterize_new_render_tree()) - - count_total_html_elements = self.get_cval( - c_val_names.count_dom_html_elements_total()) - count_document_html_elements = self.get_cval( - c_val_names.count_dom_html_elements_document()) - count_layout_boxes = self.get_cval(c_val_names.count_layout_boxes()) - count_requested_images = self.get_cval( - c_val_names.count_image_cache_requested_resources()) - - navigate_time = self.get_cval(c_val_names.time_browser_navigate()) - on_load_event_time = self.get_cval( - c_val_names.time_browser_on_load_event()) - browse_time = self.get_cval(c_val_names.time_rasterize_new_render_tree()) - usable_time = self.get_cval( - c_val_names.time_dom_html_script_element_execute()) - - count_total_html_element_recorder.collect_value(count_total_html_elements) - count_document_html_element_recorder.collect_value( - count_document_html_elements) - count_layout_box_recorder.collect_value(count_layout_boxes) - count_render_trees_recorder.collect_value(count_render_trees_end - - count_render_trees_start) - count_requested_images_recorder.collect_value(count_requested_images) - - duration_navigate_to_on_load_recorder.collect_value( - on_load_event_time - navigate_time) - duration_navigate_to_browse_recorder.collect_value( - browse_time - navigate_time) - duration_navigate_to_usable_recorder.collect_value( - usable_time - navigate_time) - - # Record the counts - count_total_html_element_recorder.on_end_test() - count_document_html_element_recorder.on_end_test() - count_layout_box_recorder.on_end_test() - count_render_trees_recorder.on_end_test() - count_requested_images_recorder.on_end_test() - - # Record the durations - tv_testcase_util.record_test_result( - STARTUP_RECORD_NAME + "DurLaunchToNavigateUs", - dur_launch_to_navigate_us) - tv_testcase_util.record_test_result( - STARTUP_RECORD_NAME + "DurLaunchToOnLoadUs", - dur_launch_to_on_load_event_us) - tv_testcase_util.record_test_result( - STARTUP_RECORD_NAME + "DurLaunchToBrowseUs", dur_launch_to_browse_us) - tv_testcase_util.record_test_result( - STARTUP_RECORD_NAME + "DurLaunchToUsableUs", dur_launch_to_usable_us) - - duration_navigate_to_on_load_recorder.on_end_test() - duration_navigate_to_browse_recorder.on_end_test() - duration_navigate_to_usable_recorder.on_end_test() - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/video/__init__.py b/src/cobalt/webdriver_benchmarks/tests/performance/video/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/video/__init__.py +++ /dev/null
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance/video/browse_to_watch.py b/src/cobalt/webdriver_benchmarks/tests/performance/video/browse_to_watch.py deleted file mode 100755 index 248e73c..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance/video/browse_to_watch.py +++ /dev/null
@@ -1,111 +0,0 @@ -#!/usr/bin/python2 -"""Simple benchmark for starting a video from browse.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import os -import sys - -# Add the base webdriver_benchmarks path -sys.path.insert(0, - os.path.dirname( - os.path.dirname((os.path.dirname( - os.path.dirname(os.path.realpath(__file__))))))) - -# pylint: disable=C6204,C6203 -import tv_testcase -import tv_testcase_event_recorder -import tv_testcase_util - -# selenium imports -keys = tv_testcase_util.import_selenium_module("webdriver.common.keys") - -MAX_VIDEO_FAILURE_COUNT = 10 -MAX_SKIPPABLE_AD_COUNT = 8 - -NUM_LOAD_TV_CALLS = 4 -NUM_ITERATIONS_PER_LOAD_TV_CALL = 25 - -BROWSE_TO_WATCH_EVENT_NAME = "wbBrowseToWatch" -BROWSE_TO_WATCH_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_UP - -WATCH_TO_BROWSE_EVENT_NAME = "wbWatchToBrowse" -WATCH_TO_BROWSE_EVENT_TYPE = tv_testcase_util.EVENT_TYPE_KEY_UP - - -class BrowseToWatchTest(tv_testcase.TvTestCase): - - class VideoFailureException(BaseException): - """Exception thrown when MAX_VIDEO_FAILURE_COUNT is exceeded.""" - - class AdvertisementFailureException(BaseException): - """Exception thrown when MAX_SKIPPABLE_AD_COUNT is exceeded.""" - - def test_simple(self): - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, BROWSE_TO_WATCH_EVENT_NAME, BROWSE_TO_WATCH_EVENT_TYPE) - recorder_options.record_animations = False - recorder_options.record_video = True - browse_to_watch_recorder = tv_testcase_event_recorder.EventRecorder( - recorder_options) - - recorder_options = tv_testcase_event_recorder.EventRecorderOptions( - self, WATCH_TO_BROWSE_EVENT_NAME, WATCH_TO_BROWSE_EVENT_TYPE) - recorder_options.record_animations = False - watch_to_browse_recorder = tv_testcase_event_recorder.EventRecorder( - recorder_options) - - failure_count = 0 - skippable_ad_count = 0 - - for _ in xrange(NUM_LOAD_TV_CALLS): - self.load_tv() - - for _ in xrange(NUM_ITERATIONS_PER_LOAD_TV_CALL): - self.send_keys(keys.Keys.ARROW_DOWN) - self.wait_for_processing_complete_after_focused_shelf() - - browse_to_watch_recorder.on_start_event() - self.send_keys(keys.Keys.ENTER) - - if not self.wait_for_media_element_playing(): - failure_count += 1 - print("Video failed to play! {} events failed.".format(failure_count)) - if failure_count > MAX_VIDEO_FAILURE_COUNT: - raise BrowseToWatchTest.VideoFailureException() - - self.send_keys(keys.Keys.ESCAPE) - self.wait_for_processing_complete_after_focused_shelf() - continue - - if self.skip_advertisement_if_playing(): - skippable_ad_count += 1 - print( - "Encountered skippable ad! {} total.".format(skippable_ad_count)) - if skippable_ad_count > MAX_SKIPPABLE_AD_COUNT: - raise BrowseToWatchTest.AdvertisementFailureException() - - self.wait_for_title_card_hidden() - self.send_keys(keys.Keys.ESCAPE) - self.wait_for_processing_complete_after_focused_shelf() - continue - - browse_to_watch_recorder.on_end_event() - - # Wait for the title card hidden before sending the escape. Otherwise, - # two escapes are required to exit the video. - self.wait_for_title_card_hidden() - - watch_to_browse_recorder.on_start_event() - self.send_keys(keys.Keys.ESCAPE) - self.wait_for_processing_complete_after_focused_shelf() - watch_to_browse_recorder.on_end_event() - - browse_to_watch_recorder.on_end_test() - watch_to_browse_recorder.on_end_test() - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance_non_video.py b/src/cobalt/webdriver_benchmarks/tests/performance_non_video.py deleted file mode 100644 index f71a433..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance_non_video.py +++ /dev/null
@@ -1,46 +0,0 @@ -#!/usr/bin/python2 -"""Target for running non-video performance test cases.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import importlib -import os -import sys -import unittest - -# The parent directory is a module -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) - -# pylint: disable=C6204,C6203 -import tv_testcase - - -def _add_test(test_suite, dir_path, test_name): - if os.path.isfile( - os.path.join(dir_path, "performance", "non_video", test_name + ".py")): - print("Adding test: {}".format(test_name)) - test_suite.addTest(unittest.TestLoader().loadTestsFromModule( - importlib.import_module("tests.performance.non_video." + test_name))) - - -# pylint: disable=unused-argument -def load_tests(loader, tests, pattern): - """This is a Python unittest "load_tests protocol method.""" - test_suite = unittest.TestSuite() - dir_path = os.path.dirname(__file__) - - # "startup" must be the first test added. The timings that it - # records require it to run first. - _add_test(test_suite, dir_path, "startup") - _add_test(test_suite, dir_path, "browse_horizontal") - _add_test(test_suite, dir_path, "browse_vertical") - _add_test(test_suite, dir_path, "browse_to_guide") - _add_test(test_suite, dir_path, "browse_to_search") - - return test_suite - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tests/performance_video.py b/src/cobalt/webdriver_benchmarks/tests/performance_video.py deleted file mode 100755 index 3784cc2..0000000 --- a/src/cobalt/webdriver_benchmarks/tests/performance_video.py +++ /dev/null
@@ -1,40 +0,0 @@ -#!/usr/bin/python2 -"""Target for running video performance test cases.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import importlib -import os -import sys -import unittest - -# The parent directory is a module -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) - -# pylint: disable=C6204,C6203 -import tv_testcase - - -def _add_test(test_suite, dir_path, test_name): - if os.path.isfile( - os.path.join(dir_path, "performance", "video", test_name + ".py")): - print("Adding test: {}".format(test_name)) - test_suite.addTest(unittest.TestLoader().loadTestsFromModule( - importlib.import_module("tests.performance.video." + test_name))) - - -# pylint: disable=unused-argument -def load_tests(loader, tests, pattern): - """This is a Python unittest "load_tests protocol method.""" - test_suite = unittest.TestSuite() - dir_path = os.path.dirname(__file__) - - _add_test(test_suite, dir_path, "browse_to_watch") - - return test_suite - - -if __name__ == "__main__": - tv_testcase.main()
diff --git a/src/cobalt/webdriver_benchmarks/tv.py b/src/cobalt/webdriver_benchmarks/tv.py deleted file mode 100644 index 332b3c9..0000000 --- a/src/cobalt/webdriver_benchmarks/tv.py +++ /dev/null
@@ -1,13 +0,0 @@ -"""CSS Constants.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -FOCUSED_GUIDE = '.focused.guide' -FOCUSED_SEARCH = '.focused.search' -FOCUSED_SHELF = '.focused.selected.shelf' -FOCUSED_SHELF_TITLE = '.focused.selected.shelf .shelf-header-title .main' -SKIP_AD_BUTTON_CAN_SKIP = '.skip-ad-button.canskip' -SKIP_AD_BUTTON_HIDDEN = '.skip-ad-button.hidden' -TITLE_CARD_HIDDEN = '.title-card.hidden'
diff --git a/src/cobalt/webdriver_benchmarks/tv_testcase.py b/src/cobalt/webdriver_benchmarks/tv_testcase.py deleted file mode 100644 index dc49278..0000000 --- a/src/cobalt/webdriver_benchmarks/tv_testcase.py +++ /dev/null
@@ -1,343 +0,0 @@ -"""Base class for WebDriver tests.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import json -import logging -import os -import sys -import time -import unittest - -# This directory is a package -sys.path.insert(0, os.path.abspath(".")) -# pylint: disable=C6204,C6203 -import c_val_names -import tv -import tv_testcase_runner -import tv_testcase_util - -try: - import custom_query_param_constants as query_param_constants -except ImportError: - import default_query_param_constants as query_param_constants - -# selenium imports -# pylint: disable=C0103 -ActionChains = tv_testcase_util.import_selenium_module( - submodule="webdriver.common.action_chains").ActionChains -keys = tv_testcase_util.import_selenium_module("webdriver.common.keys") - -WINDOWDRIVER_CREATED_TIMEOUT_SECONDS = 30 -WEBMODULE_LOADED_TIMEOUT_SECONDS = 30 -PAGE_LOAD_WAIT_SECONDS = 30 -PROCESSING_TIMEOUT_SECONDS = 60 -HTML_SCRIPT_ELEMENT_EXECUTE_TIMEOUT_SECONDS = 30 -MEDIA_TIMEOUT_SECONDS = 30 -SKIP_AD_TIMEOUT_SECONDS = 30 -TITLE_CARD_HIDDEN_TIMEOUT_SECONDS = 30 - -_is_initialized = False - - -class TvTestCase(unittest.TestCase): - """Base class for WebDriver tests. - - Style note: snake_case is used for function names here so as to match - with an internal class with the same name. - """ - - class WindowDriverCreatedTimeoutException(BaseException): - """Exception thrown when WindowDriver was not created in time.""" - - class WebModuleLoadedTimeoutException(BaseException): - """Exception thrown when WebModule was not loaded in time.""" - - class ProcessingTimeoutException(BaseException): - """Exception thrown when processing did not complete in time.""" - - class HtmlScriptElementExecuteTimeoutException(BaseException): - """Exception thrown when processing did not complete in time.""" - - class TitleCardHiddenTimeoutException(BaseException): - """Exception thrown when title card did not disappear in time.""" - - @classmethod - def setUpClass(cls): - print("Running " + cls.__name__) - - @classmethod - def tearDownClass(cls): - print("Done " + cls.__name__) - - def setUp(self): - global _is_initialized - if not _is_initialized: - # Initialize the tests. - query_params = query_param_constants.INIT_QUERY_PARAMS - triggers_reload = query_param_constants.INIT_QUERY_PARAMS_TRIGGER_RELOAD - self.load_tv(query_params, triggers_reload) - _is_initialized = True - - def get_webdriver(self): - return tv_testcase_runner.GetWebDriver() - - def get_default_url(self): - return tv_testcase_runner.GetDefaultUrl() - - def get_cval(self, cval_name): - """Returns the Python object represented by a JSON cval string. - - Args: - cval_name: Name of the cval. - Returns: - Python object represented by the JSON cval string - """ - javascript_code = "return h5vcc.cVal.getValue('{}')".format(cval_name) - json_result = self.get_webdriver().execute_script(javascript_code) - if json_result is None: - return None - else: - return json.loads(json_result) - - def load_blank(self): - """Loads about:blank and waits for it to finish. - - Raises: - Underlying WebDriver exceptions - """ - self.clear_url_loaded_events() - self.get_webdriver().get("about:blank") - self.wait_for_url_loaded_events() - - def load_tv(self, query_params=None, triggers_reload=False): - """Loads the main TV page and waits for it to display. - - Args: - query_params: A dict containing additional query parameters. - triggers_reload: Whether or not the navigation will trigger a reload. - Raises: - Underlying WebDriver exceptions - """ - self.get_webdriver().execute_script("h5vcc.storage.clearCookies()") - self.clear_url_loaded_events() - self.get_webdriver().get( - tv_testcase_util.generate_url(self.get_default_url(), query_params)) - self.wait_for_url_loaded_events() - if triggers_reload: - self.clear_url_loaded_events() - self.wait_for_url_loaded_events() - # Note that the internal tests use "expect_transition" which is - # a mechanism that sets a maximum timeout for a "@with_retries" - # decorator-driven success retry loop for subsequent webdriver requests. - # - # We'll skip that sophistication here. - self.wait_for_processing_complete_after_focused_shelf() - - def poll_until_found(self, css_selector): - """Polls until an element is found. - - Args: - css_selector: A CSS selector - Raises: - Underlying WebDriver exceptions - """ - start_time = time.time() - while ((not self.find_elements(css_selector)) and - (time.time() - start_time < PAGE_LOAD_WAIT_SECONDS)): - time.sleep(1) - self.assert_displayed(css_selector) - - def unique_find(self, unique_selector): - """Finds and returns a uniquely selected element. - - Args: - unique_selector: A CSS selector that will select only one element - Raises: - Underlying WebDriver exceptions - AssertError: the element isn't unique - Returns: - Element - """ - return self.find_elements(unique_selector, expected_num=1)[0] - - def assert_displayed(self, css_selector): - """Asserts that an element is displayed. - - Args: - css_selector: A CSS selector - Raises: - Underlying WebDriver exceptions - AssertError: the element isn't found - """ - # TODO does not actually assert that it's visible, like webdriver.py - # probably does. - self.assertTrue(self.unique_find(css_selector)) - - def find_elements(self, css_selector, expected_num=None): - """Finds elements based on a selector. - - Args: - css_selector: A CSS selector - expected_num: Expected number of matching elements - Raises: - Underlying WebDriver exceptions - AssertError: expected_num isn't met - Returns: - Array of selected elements - """ - elements = self.get_webdriver().find_elements_by_css_selector(css_selector) - if expected_num is not None: - self.assertEqual(len(elements), expected_num) - return elements - - def send_keys(self, key_events): - """Sends keys to whichever element currently has focus. - - Args: - key_events: key events - - Raises: - Underlying WebDriver exceptions - """ - ActionChains(self.get_webdriver()).send_keys(key_events).perform() - - def clear_url_loaded_events(self): - """Clear the events that indicate that Cobalt finished loading a URL.""" - tv_testcase_runner.GetWindowDriverCreated().clear() - tv_testcase_runner.GetWebModuleLoaded().clear() - - def wait_for_url_loaded_events(self): - """Wait for the events indicating that Cobalt finished loading a URL.""" - windowdriver_created = tv_testcase_runner.GetWindowDriverCreated() - if not windowdriver_created.wait(WINDOWDRIVER_CREATED_TIMEOUT_SECONDS): - raise TvTestCase.WindowDriverCreatedTimeoutException() - - webmodule_loaded = tv_testcase_runner.GetWebModuleLoaded() - if not webmodule_loaded.wait(WEBMODULE_LOADED_TIMEOUT_SECONDS): - raise TvTestCase.WebModuleLoadedTimeoutException() - - def wait_for_processing_complete_after_focused_shelf(self): - """Waits for Cobalt to focus on a shelf and complete pending layouts.""" - self.poll_until_found(tv.FOCUSED_SHELF) - self.assert_displayed(tv.FOCUSED_SHELF_TITLE) - self.wait_for_processing_complete() - - def wait_for_processing_complete(self, check_animations=True): - """Waits for Cobalt to complete processing. - - This method requires two consecutive iterations through its loop where - Cobalt is not processing before treating processing as complete. This - protects against a brief window between two different processing sections - being mistaken as completed processing. - - Args: - check_animations: Whether or not animations should be checked when - determining if processing is complete. - - Raises: - ProcessingTimeoutException: Processing is not complete within the - required time. - """ - start_time = time.time() - - # First simply check for whether or not the event is still processing. - # There's no need to check anything else while the event is still going on. - # Once it is done processing, it won't get re-set, so there's no need to - # re-check it. - while self.get_cval(c_val_names.event_is_processing()): - if time.time() - start_time > PROCESSING_TIMEOUT_SECONDS: - raise TvTestCase.ProcessingTimeoutException() - - time.sleep(0.1) - - # Now wait for all processing to complete in Cobalt. - count = 0 - while count < 2: - if self.is_processing(check_animations): - count = 0 - else: - count += 1 - - if time.time() - start_time > PROCESSING_TIMEOUT_SECONDS: - raise TvTestCase.ProcessingTimeoutException() - - time.sleep(0.1) - - def is_processing(self, check_animations): - """Checks to see if Cobalt is currently processing.""" - return (self.get_cval(c_val_names.count_dom_active_java_script_events()) or - self.get_cval(c_val_names.layout_is_dirty()) or - (check_animations and - self.get_cval(c_val_names.renderer_has_active_animations())) or - self.get_cval(c_val_names.count_image_cache_loading_resources())) - - def wait_for_html_script_element_execute_count(self, required_count): - """Waits for specified number of html script element Execute() calls. - - Args: - required_count: the number of executions that must occur - - Raises: - HtmlScriptElementExecuteTimeoutException: The required html script element - executions did not occur within the required time. - """ - start_time = time.time() - while self.get_cval( - c_val_names.count_dom_html_script_element_execute()) < required_count: - if time.time() - start_time > HTML_SCRIPT_ELEMENT_EXECUTE_TIMEOUT_SECONDS: - raise TvTestCase.HtmlScriptElementExecuteTimeoutException() - time.sleep(0.1) - - def wait_for_media_element_playing(self): - """Waits for a video to begin playing. - - Returns: - Whether or not the video started. - """ - start_time = time.time() - while self.get_cval( - c_val_names.event_duration_dom_video_start_delay()) == 0: - if time.time() - start_time > MEDIA_TIMEOUT_SECONDS: - return False - time.sleep(0.1) - - return True - - def skip_advertisement_if_playing(self): - """Waits to skip an ad if it is encountered. - - Returns: - True if a skippable advertisement was encountered - """ - start_time = time.time() - if not self.find_elements(tv.SKIP_AD_BUTTON_HIDDEN): - while not self.find_elements(tv.SKIP_AD_BUTTON_CAN_SKIP): - if time.time() - start_time > SKIP_AD_TIMEOUT_SECONDS: - return True - time.sleep(0.1) - self.send_keys(keys.Keys.ENTER) - self.wait_for_processing_complete(False) - return True - - return False - - def wait_for_title_card_hidden(self): - """Waits for the title to disappear while a video is playing. - - Raises: - TitleCardHiddenTimeoutException: The title card did not become hidden in - the required time. - """ - start_time = time.time() - while not self.find_elements(tv.TITLE_CARD_HIDDEN): - if time.time() - start_time > TITLE_CARD_HIDDEN_TIMEOUT_SECONDS: - raise TvTestCase.TitleCardHiddenTimeoutException() - time.sleep(1) - - -def main(): - logging.basicConfig(level=logging.DEBUG) - tv_testcase_runner.main()
diff --git a/src/cobalt/webdriver_benchmarks/tv_testcase_event_recorder.py b/src/cobalt/webdriver_benchmarks/tv_testcase_event_recorder.py deleted file mode 100644 index 5905e84..0000000 --- a/src/cobalt/webdriver_benchmarks/tv_testcase_event_recorder.py +++ /dev/null
@@ -1,262 +0,0 @@ -#!/usr/bin/python2 -"""Records stats on an event injected by a benchmark test.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import c_val_names -import tv_testcase_util - - -class EventRecorderOptions(object): - """Contains all of the parameters needed by EventRecorder.""" - - def __init__(self, test, event_name, event_type): - """Initializes the event recorder options. - - Args: - test: specific benchmark test being run - event_name: name of the event being recorded - event_type: type of event being recorded (tv_testcase_util.py) - """ - self.test = test - self.event_name = event_name - self.event_type = event_type - - self.record_animations = True - self.record_video = False - - -class EventRecorder(object): - """Records stats on an event injected by a benchmark test. - - Handles collecting event data over all of the instances of a specific event - injected by a benchmark test and records statistics on the data when the test - ends. The specific event types that can be injected are listed within - tv_testcase_util.py. - - Both rasterize animations and video start delay data can potentially be - recorded, depending on the |record_animations| and |record_video| option - flags. - """ - - def __init__(self, options): - """Initializes the event recorder. - - Handles setting up this event recorder, including creating all of its - recorders, based upon the passed in options. - - Args: - options: the settings to use in creating this event recorder - """ - self.test = options.test - self.event_name = options.event_name - self.event_type = options.event_type - - self.render_tree_failure_count = 0 - - # Each entry in the list contains a tuple with a key and value recorder. - self.value_dictionary_recorders = [] - - # Optional animations recorders - self.animations_recorder = None - self.animations_start_delay_recorder = None - self.animations_end_delay_recorder = None - - # Optional video recorders - self.video_delay_recorder = None - - # Count record strategies - count_record_strategies = [] - count_record_strategies.append(tv_testcase_util.RecordStrategyMean()) - count_record_strategies.append(tv_testcase_util.RecordStrategyMedian()) - count_record_strategies.append(tv_testcase_util.RecordStrategyMax()) - - # Duration record strategies - duration_record_strategies = [] - duration_record_strategies.append(tv_testcase_util.RecordStrategyMean()) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(25)) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(50)) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(75)) - duration_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(95)) - - # Video delay record strategies - video_delay_record_strategies = [] - video_delay_record_strategies.append(tv_testcase_util.RecordStrategyMean()) - video_delay_record_strategies.append(tv_testcase_util.RecordStrategyMin()) - video_delay_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(25)) - video_delay_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(50)) - video_delay_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(75)) - video_delay_record_strategies.append( - tv_testcase_util.RecordStrategyPercentile(95)) - video_delay_record_strategies.append(tv_testcase_util.RecordStrategyMax()) - - # Dictionary count recorders - self._add_value_dictionary_recorder("CntDomEventListeners", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomNodes", count_record_strategies) - self._add_value_dictionary_recorder("CntDomHtmlElements", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomDocumentHtmlElements", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomHtmlElementsCreated", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomUpdateMatchingRules", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomUpdateComputedStyle", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomGenerateHtmlComputedStyle", - count_record_strategies) - self._add_value_dictionary_recorder("CntDomGeneratePseudoComputedStyle", - count_record_strategies) - self._add_value_dictionary_recorder("CntLayoutBoxes", - count_record_strategies) - self._add_value_dictionary_recorder("CntLayoutBoxesCreated", - count_record_strategies) - self._add_value_dictionary_recorder("CntLayoutUpdateSize", - count_record_strategies) - self._add_value_dictionary_recorder("CntLayoutRenderAndAnimate", - count_record_strategies) - self._add_value_dictionary_recorder("CntLayoutUpdateCrossReferences", - count_record_strategies) - - # Dictionary duration recorders - self._add_value_dictionary_recorder("DurTotalUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurDomInjectEventUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurDomRunAnimationFrameCallbacksUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurDomUpdateComputedStyleUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurLayoutBoxTreeUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurLayoutBoxTreeBoxGenerationUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurLayoutBoxTreeUpdateUsedSizesUs", - duration_record_strategies) - self._add_value_dictionary_recorder("DurLayoutRenderAndAnimateUs", - duration_record_strategies) - - self.count_render_trees_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "CntRenderTrees", count_record_strategies) - self.count_requested_images_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "CntRequestedImages", count_record_strategies) - - # Optional animations recorder - if options.record_animations: - self.animations_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "DurRasterizeAnimationsUs", - duration_record_strategies) - self.animations_start_delay_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "DurAnimationsStartDelayUs", - duration_record_strategies) - self.animations_end_delay_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "DurAnimationsEndDelayUs", - duration_record_strategies) - - self.final_render_tree_delay_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "DurFinalRenderTreeDelayUs", - duration_record_strategies) - - # Optional video recorder - if options.record_video: - self.video_delay_recorder = tv_testcase_util.ResultsRecorder( - self.event_name + "DurVideoStartDelayUs", - video_delay_record_strategies) - - def _add_value_dictionary_recorder(self, key, record_strategies): - recorder = tv_testcase_util.ResultsRecorder(self.event_name + key, - record_strategies) - self.value_dictionary_recorders.append((key, recorder)) - - def on_start_event(self): - """Handles logic related to the start of the event instance.""" - self.count_render_trees_start = self.test.get_cval( - c_val_names.count_rasterize_new_render_tree()) - self.count_requested_images_start = self.test.get_cval( - c_val_names.count_image_cache_requested_resources()) - - def on_end_event(self): - """Handles logic related to the end of the event instance.""" - - value_dictionary = self.test.get_cval( - c_val_names.event_value_dictionary(self.event_type)) - - # If the event failed to produce a render tree, then its data is not - # collected. Log the failure and return. - if not value_dictionary or not value_dictionary.get("ProducedRenderTree"): - self.render_tree_failure_count += 1 - print("{} event failed to produce render tree! {} events failed.".format( - self.event_name, self.render_tree_failure_count)) - return - - event_start_time = value_dictionary.get("StartTime") - - # Record all of the values from the event. - for value_dictionary_recorder in self.value_dictionary_recorders: - value = value_dictionary.get(value_dictionary_recorder[0]) - if value is not None: - value_dictionary_recorder[1].collect_value(value) - - self.count_render_trees_end = self.test.get_cval( - c_val_names.count_rasterize_new_render_tree()) - self.count_render_trees_recorder.collect_value( - self.count_render_trees_end - self.count_render_trees_start) - - self.count_requested_images_end = self.test.get_cval( - c_val_names.count_image_cache_requested_resources()) - self.count_requested_images_recorder.collect_value( - self.count_requested_images_end - self.count_requested_images_start) - - if self.animations_recorder: - animation_entries = self.test.get_cval( - c_val_names.rasterize_animations_entry_list()) - for value in animation_entries: - self.animations_recorder.collect_value(value) - - animations_start_time = self.test.get_cval( - c_val_names.time_rasterize_animations_start()) - self.animations_start_delay_recorder.collect_value( - animations_start_time - event_start_time) - animations_end_time = self.test.get_cval( - c_val_names.time_rasterize_animations_end()) - self.animations_end_delay_recorder.collect_value(animations_end_time - - event_start_time) - - final_render_tree_time = self.test.get_cval( - c_val_names.time_rasterize_new_render_tree()) - self.final_render_tree_delay_recorder.collect_value(final_render_tree_time - - event_start_time) - - if self.video_delay_recorder: - self.video_delay_recorder.collect_value( - self.test.get_cval( - c_val_names.event_duration_dom_video_start_delay())) - - def on_end_test(self): - """Handles logic related to the end of the test.""" - - for value_dictionary_recorder in self.value_dictionary_recorders: - value_dictionary_recorder[1].on_end_test() - - self.count_render_trees_recorder.on_end_test() - self.count_requested_images_recorder.on_end_test() - - if self.animations_recorder: - self.animations_recorder.on_end_test() - self.animations_start_delay_recorder.on_end_test() - self.animations_end_delay_recorder.on_end_test() - - self.final_render_tree_delay_recorder.on_end_test() - - if self.video_delay_recorder: - self.video_delay_recorder.on_end_test()
diff --git a/src/cobalt/webdriver_benchmarks/tv_testcase_runner.py b/src/cobalt/webdriver_benchmarks/tv_testcase_runner.py deleted file mode 100755 index 45c8556..0000000 --- a/src/cobalt/webdriver_benchmarks/tv_testcase_runner.py +++ /dev/null
@@ -1,297 +0,0 @@ -#!/usr/bin/python2 -"""Runs webdriver-based Cobalt benchmark tests.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import argparse -import importlib -import inspect -import os -import re -import sys -import thread -import threading -import unittest - -import tv_testcase_util - -arg_parser = argparse.ArgumentParser( - description="Runs Webdriver-based Cobalt benchmark tests") -arg_parser.add_argument( - "-p", - "--platform", - help="Cobalt platform, eg 'linux-x64x11'." - "Fetched from environment if absent.") -arg_parser.add_argument( - "-e", - "--executable", - help="Path to Cobalt executable. " - "Auto-derived if absent.") -arg_parser.add_argument( - "-c", - "--config", - choices=["debug", "devel", "qa", "gold"], - help="Build config (eg, 'qa' or 'devel'). Not used if " - "--executable is specified. Fetched from environment " - "if needed and absent.") -arg_parser.add_argument( - "-d", - "--devkit_name", - help="Devkit or IP address for app_launcher." - "Current hostname used if absent.") -arg_parser.add_argument( - "--command_line", - nargs="*", - help="Command line arguments to pass to the Cobalt executable.") -arg_parser.add_argument( - "--url", help="Specifies the URL to run the tests against.") -arg_parser.add_argument( - "-o", "--log_file", help="Logfile pathname. stdout if absent.") - -# Pattern to match Cobalt log line for when the WebDriver port has been -# opened. -RE_WEBDRIVER_LISTEN = re.compile(r"Starting WebDriver server on port (\d+)") -# Pattern to match Cobalt log line for when a WindowDriver has been created. -RE_WINDOWDRIVER_CREATED = re.compile( - r"^\[\d+/\d+:INFO:browser_module\.cc\(\d+\)\] Created WindowDriver: ID=\S+") -# Pattern to match Cobalt log line for when a WebModule is has been loaded. -RE_WEBMODULE_LOADED = re.compile( - r"^\[\d+/\d+:INFO:browser_module\.cc\(\d+\)\] Loaded WebModule") - -DEFAULT_STARTUP_TIMEOUT_SECONDS = 2 * 60 -WEBDRIVER_HTTP_TIMEOUT_SECONDS = 2 * 60 -COBALT_EXIT_TIMEOUT_SECONDS = 5 - -COBALT_WEBDRIVER_CAPABILITIES = { - "browserName": "cobalt", - "javascriptEnabled": True, - "platform": "LINUX" -} - -_webdriver = None -_windowdriver_created = threading.Event() -_webmodule_loaded = threading.Event() -_default_url = "https://www.youtube.com/tv" - - -def GetWebDriver(): - """Returns the active connect WebDriver instance.""" - return _webdriver - - -def GetWindowDriverCreated(): - """Returns the WindowDriver created instance.""" - return _windowdriver_created - - -def GetWebModuleLoaded(): - """Returns the WebModule loaded instance.""" - return _webmodule_loaded - - -def GetDefaultUrl(): - """Returns the default url to use with tests.""" - return _default_url - - -class TimeoutException(Exception): - pass - - -class CobaltRunner(object): - """Runs a Cobalt browser w/ a WebDriver client attached.""" - test_script_started = threading.Event() - selenium_webdriver_module = None - webdriver = None - launcher = None - log_file_path = None - thread = None - failed = False - should_exit = threading.Event() - - def __init__(self, platform, executable, devkit_name, command_line_args, - default_url, log_file_path): - global _default_url - if default_url is not None: - _default_url = default_url - - self.selenium_webdriver_module = tv_testcase_util.import_selenium_module( - "webdriver") - - script_path = os.path.realpath(inspect.getsourcefile(lambda: 0)) - app_launcher_path = os.path.realpath( - os.path.join( - os.path.dirname(script_path), "..", "..", "tools", "lbshell")) - sys.path.append(app_launcher_path) - app_launcher = importlib.import_module("app_launcher") - self.launcher = app_launcher.CreateLauncher( - platform, executable, devkit_name=devkit_name, close_output_file=False) - - args = [] - if command_line_args is not None: - for command_line_arg in command_line_args: - args.append("--" + command_line_arg) - args.append("--enable_webdriver") - args.append("--debug_console=off") - args.append("--disable_image_animations") - args.append("--null_savegame") - args.append("--url=" + _default_url) - - self.launcher.SetArgs(args) - self.launcher.SetOutputCallback(self._HandleLine) - self.log_file_path = log_file_path - self.log_file = None - - def __enter__(self): - self.thread = threading.Thread(target=self.Run) - self.thread.start() - try: - self.WaitForStart() - except KeyboardInterrupt: - # potentially from thread.interrupt_main(). We will treat as - # a timeout regardless - self.SetShouldExit(failed=True) - raise TimeoutException - return self - - def __exit__(self, exc_type, exc_value, traceback): - # The unittest module terminates with a SystemExit - # If this is a successful exit, then this is a successful run - success = exc_type is None or (exc_type is SystemExit and - not exc_value.code) - self.SetShouldExit(failed=not success) - self.thread.join(COBALT_EXIT_TIMEOUT_SECONDS) - - def _HandleLine(self, line): - """Internal log line callback.""" - - if RE_WINDOWDRIVER_CREATED.search(line): - _windowdriver_created.set() - return - - if RE_WEBMODULE_LOADED.search(line): - _webmodule_loaded.set() - return - - # Wait for WebDriver port here then connect - if self.test_script_started.is_set(): - return - - match = RE_WEBDRIVER_LISTEN.search(line) - if not match: - return - - port = match.group(1) - print("WebDriver port opened:" + port + "\n", file=self.log_file) - self._StartWebdriver(port) - - def SetShouldExit(self, failed=False): - """Indicates cobalt process should exit.""" - self.failed = failed - self.should_exit.set() - self.launcher.SendKill() - - def _GetProcessIPAddress(self): - return self.launcher.GetProcessIPAddress() - - def _StartWebdriver(self, port): - global _webdriver - url = "http://{}:{}/".format(self._GetProcessIPAddress(), port) - self.webdriver = self.selenium_webdriver_module.Remote( - url, COBALT_WEBDRIVER_CAPABILITIES) - self.webdriver.command_executor.set_timeout(WEBDRIVER_HTTP_TIMEOUT_SECONDS) - print("Selenium Connected\n", file=self.log_file) - _webdriver = self.webdriver - self.test_script_started.set() - - def WaitForStart(self): - """Waits for the webdriver client to attach to Cobalt.""" - startup_timeout_seconds = self.launcher.GetStartupTimeout() - if not startup_timeout_seconds: - startup_timeout_seconds = DEFAULT_STARTUP_TIMEOUT_SECONDS - - if not self.test_script_started.wait(startup_timeout_seconds): - self.SetShouldExit(failed=True) - raise TimeoutException - print("Cobalt started", file=self.log_file) - - def Run(self): - """Thread run routine.""" - - # Use stdout if log_file_path is unspecified - # If log_file_path is specified, make sure to close it - to_close = None - try: - if self.log_file_path: - self.log_file = open(self.log_file_path, "w") - to_close = self.log_file - else: - self.log_file = sys.stdout - - self.launcher.SetOutputFile(self.log_file) - print("Running launcher", file=self.log_file) - self.launcher.Run() - print( - "Cobalt terminated. failed: " + str(self.failed), file=self.log_file) - # This is watched for in webdriver_benchmark_test.py - if not self.failed: - print("{}\n".format(tv_testcase_util.TEST_COMPLETE)) - # pylint: disable=broad-except - except Exception as ex: - print("Exception running Cobalt " + str(ex), file=sys.stderr) - finally: - if to_close: - to_close.close() - if not self.should_exit.is_set(): - # If the main thread is not expecting us to exit, - # we must interrupt it. - thread.interrupt_main() - return 0 - - -def GetCobaltExecutablePath(platform, config): - """Auto-derives a path to a cobalt executable.""" - if config is None: - try: - config = os.environ["BUILD_TYPE"] - except KeyError: - sys.stderr.write("Must specify --config or --executable\n") - sys.exit(1) - script_path = os.path.realpath(inspect.getsourcefile(lambda: 0)) - script_dir = os.path.dirname(script_path) - out_dir = os.path.join(script_dir, "..", "..", "out") - executable_directory = os.path.join(out_dir, "{}_{}".format(platform, config)) - return os.path.join(executable_directory, "cobalt") - - -def main(): - args = arg_parser.parse_args() - # Keep unittest module from seeing these args - sys.argv = sys.argv[:1] - - platform = args.platform - if platform is None: - try: - platform = os.environ["BUILD_PLATFORM"] - except KeyError: - sys.stderr.write("Must specify --platform\n") - sys.exit(1) - - executable = args.executable - if executable is None: - executable = GetCobaltExecutablePath(platform, args.config) - - try: - with CobaltRunner(platform, executable, args.devkit_name, args.command_line, - args.url, args.log_file) as runner: - unittest.main(testRunner=unittest.TextTestRunner( - verbosity=0, stream=runner.log_file)) - except TimeoutException: - print("Timeout waiting for Cobalt to start", file=sys.stderr) - sys.exit(1) - - -if __name__ == "__main__": - main()
diff --git a/src/cobalt/webdriver_benchmarks/tv_testcase_util.py b/src/cobalt/webdriver_benchmarks/tv_testcase_util.py deleted file mode 100644 index 6cb9a52..0000000 --- a/src/cobalt/webdriver_benchmarks/tv_testcase_util.py +++ /dev/null
@@ -1,200 +0,0 @@ -"""Provides constants and functions needed by tv_testcase classes.""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import importlib -import json -import sys - -# pylint: disable=C6204 -from urllib import urlencode -import urlparse - -import container_util - -try: - import custom_query_param_constants as query_param_constants -except ImportError: - import default_query_param_constants as query_param_constants - -# These are watched for in webdriver_benchmark_test.py -TEST_RESULT = "webdriver_benchmark TEST RESULT" -TEST_COMPLETE = "webdriver_benchmark TEST COMPLETE" - -# These are event types that can be injected -EVENT_TYPE_KEY_DOWN = "KeyDown" -EVENT_TYPE_KEY_UP = "KeyUp" - - -def import_selenium_module(submodule=None): - """Dynamically imports a selenium.webdriver submodule. - - This is done because selenium 3.0 is not commonly pre-installed - on workstations, and we want to have a friendly error message for that - case. - - Args: - submodule: module subpath underneath "selenium.webdriver" - Returns: - appropriate module - """ - if submodule: - module_path = ".".join(("selenium", submodule)) - else: - module_path = "selenium" - # As of this writing, Google uses selenium 3.0.0b2 internally, so - # thats what we will target here as well. - try: - module = importlib.import_module(module_path) - if submodule is None: - # Only the top-level module has __version__ - if not module.__version__.startswith("3.0"): - raise ImportError("Not version 3.0.x") - except ImportError: - sys.stderr.write("Could not import {}\n" - "Please install selenium >= 3.0.0b2.\n" - "Commonly: \"sudo pip install 'selenium>=3.0.0b2'\"\n" - .format(module_path)) - sys.exit(1) - return module - - -def generate_url(default_url, query_params_override=None): - """Returns the URL indicated by the path and query parameters. - - Args: - default_url: the default url to use; its query params may be overridden - query_params_override: optional query params that override the ones - contained within the default URL - Returns: - the url generated from the parameters - """ - parsed_url = list(urlparse.urlparse(default_url)) - - query_params = query_param_constants.BASE_QUERY_PARAMS - if query_params_override: - query_params.update(query_params_override) - else: - query_params.update(urlparse.parse_qsl(parsed_url[4])) - - parsed_url[4] = urlencode(query_params, doseq=True) - return urlparse.urlunparse(parsed_url) - - -def record_test_result(name, result): - """Records an individual scalar result of a benchmark test. - - Args: - name: string name of test case - result: Test result. Must be JSON encodable scalar. - """ - value_to_record = result - - string_value_to_record = json.JSONEncoder().encode(value_to_record) - print("{}: {} {}\n".format(TEST_RESULT, name, string_value_to_record)) - sys.stdout.flush() - - -class RecordStrategyMax(object): - """"Records the max of an array of values.""" - - def run(self, name, values): - """Records the max of an array of values. - - Args: - name: string name of test case - values: must be array of JSON encodable scalar - """ - record_test_result("{}Max".format(name), max(values)) - - -class RecordStrategyMin(object): - """"Records the min of an array of values.""" - - def run(self, name, values): - """Records the min of an array of values. - - Args: - name: string name of test case - values: must be array of JSON encodable scalar - """ - record_test_result("{}Min".format(name), min(values)) - - -class RecordStrategyMean(object): - """"Records the mean of an array of values.""" - - def run(self, name, values): - """Records the mean of an array of values. - - Args: - name: string name of test case - values: must be array of JSON encodable scalar - """ - record_test_result("{}Mean".format(name), container_util.mean(values)) - - -class RecordStrategyMedian(object): - """"Records the median of an array of test results.""" - - def run(self, name, values): - """Records the median of an array of values. - - Args: - name: string name of test case - values: must be array of JSON encodable scalar - """ - record_test_result("{}Median".format(name), - container_util.percentile(values, 50)) - - -class RecordStrategyPercentile(object): - """"Records the specified percentile of an array of test results.""" - - def __init__(self, percentile): - """Initializes the record strategy. - - Args: - percentile: the percentile to record - """ - self.percentile = percentile - - def run(self, name, values): - """Records the percentile of an array of values. - - Args: - name: string name of test case - values: must be array of JSON encodable scalar - Raises: - RuntimeError: Raised on invalid args. - """ - record_test_result("{}Pct{}".format(name, self.percentile), - container_util.percentile(values, self.percentile)) - - -class ResultsRecorder(object): - """"Collects values and records results after a benchmark test ends.""" - - def __init__(self, name, record_strategies): - """Initializes the value recorder. - - Args: - name: the name to use when recording test results - record_strategies: the strategies to use when the test ends - """ - self.name = name - self.record_strategies = record_strategies - self.values = [] - - def collect_value(self, value): - self.values.append(value) - - def on_end_test(self): - """Handles logic related to the end of the benchmark test.""" - - # Only run the strategies if values have been collected. - if self.values: - for record_strategy in self.record_strategies: - record_strategy.run(self.name, self.values)
diff --git a/src/net/url_request/url_request_job_manager.cc b/src/net/url_request/url_request_job_manager.cc index 1ab6814..ed0f5db 100644 --- a/src/net/url_request/url_request_job_manager.cc +++ b/src/net/url_request/url_request_job_manager.cc
@@ -39,9 +39,7 @@ static const SchemeToFactory kBuiltinFactories[] = { {"https", URLRequestHttpJob::Factory}, {"data", URLRequestDataJob::Factory}, -#if !defined(COBALT_FORCE_HTTPS) { "http", URLRequestHttpJob::Factory }, -#endif #if defined(COBALT_ENABLE_FILE_SCHEME) { "file", URLRequestFileJob::Factory }, #endif
diff --git a/src/starboard/client_porting/eztime/eztime.cc b/src/starboard/client_porting/eztime/eztime.cc index 10c86f4..aa4f737 100644 --- a/src/starboard/client_porting/eztime/eztime.cc +++ b/src/starboard/client_porting/eztime/eztime.cc
@@ -115,8 +115,17 @@ SB_DCHECK(value); SB_DCHECK(out_exploded); UErrorCode status = U_ZERO_ERROR; + + // Always query the time using a gregorian calendar. This is + // implied in opengroup documentation for tm struct, even though it is not + // specified. E.g. in gmtime's documentation, it states that UTC time is + // used, and in tm struct's documentation it is specified that year should + // be an offset from 1900. + + // See: + // http://pubs.opengroup.org/onlinepubs/009695399/functions/gmtime.html UCalendar* calendar = ucal_open(GetTimeZoneId(timezone), -1, - uloc_getDefault(), UCAL_DEFAULT, &status); + uloc_getDefault(), UCAL_GREGORIAN, &status); if (!calendar) { return false; } @@ -157,8 +166,17 @@ EzTimeZone timezone) { SB_DCHECK(exploded); UErrorCode status = U_ZERO_ERROR; + + // Always query the time using a gregorian calendar. This is + // implied in opengroup documentation for tm struct, even though it is not + // specified. E.g. in gmtime's documentation, it states that UTC time is + // used, and in tm struct's documentation it is specified that year should + // be an offset from 1900. + + // See: + // http://pubs.opengroup.org/onlinepubs/009695399/functions/gmtime.html UCalendar* calendar = ucal_open(GetTimeZoneId(timezone), -1, - uloc_getDefault(), UCAL_DEFAULT, &status); + uloc_getDefault(), UCAL_GREGORIAN, &status); if (!calendar) { EzTimeValue zero_time = {}; return zero_time;
diff --git a/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc b/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc index 0a96110..bdf679d 100644 --- a/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc +++ b/src/starboard/shared/starboard/media/media_can_play_mime_and_key_system.cc
@@ -257,6 +257,14 @@ } } + std::string cryptoblockformat = + mime_type.GetParamStringValue("cryptoblockformat", ""); + if (!cryptoblockformat.empty()) { + if (mime_type.subtype() != "webm" || cryptoblockformat != "subsample") { + return kSbMediaSupportTypeNotSupported; + } + } + int width = 0; int height = 0; int fps = 0;