// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/renderer/rasterizer/egl/render_tree_node_visitor.h"

#include <algorithm>
#include <cmath>

#include "base/debug/trace_event.h"
#include "base/optional.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/type_id.h"
#include "cobalt/math/matrix3_f.h"
#include "cobalt/math/transform_2d.h"
#include "cobalt/renderer/rasterizer/common/utils.h"
#include "cobalt/renderer/rasterizer/egl/draw_poly_color.h"
#include "cobalt/renderer/rasterizer/egl/draw_rect_color_texture.h"
#include "cobalt/renderer/rasterizer/egl/draw_rect_linear_gradient.h"
#include "cobalt/renderer/rasterizer/egl/draw_rect_shadow_blur.h"
#include "cobalt/renderer/rasterizer/egl/draw_rect_shadow_spread.h"
#include "cobalt/renderer/rasterizer/egl/draw_rect_texture.h"
#include "cobalt/renderer/rasterizer/skia/hardware_image.h"
#include "cobalt/renderer/rasterizer/skia/image.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace egl {

namespace {

math::Rect RoundRectFToInt(const math::RectF& input) {
  int left = static_cast<int>(input.x() + 0.5f);
  int right = static_cast<int>(input.right() + 0.5f);
  int top = static_cast<int>(input.y() + 0.5f);
  int bottom = static_cast<int>(input.bottom() + 0.5f);
  return math::Rect(left, top, right - left, bottom - top);
}

bool IsOnlyScaleAndTranslate(const math::Matrix3F& matrix) {
  return matrix(2, 0) == 0 && matrix(2, 1) == 0 && matrix(2, 2) == 1 &&
         matrix(0, 1) == 0 && matrix(1, 0) == 0;
}

math::Matrix3F GetTexcoordTransform(
    const OffscreenTargetManager::TargetInfo& target) {
  float scale_x = 1.0f / target.framebuffer->GetSize().width();
  float scale_y = 1.0f / target.framebuffer->GetSize().height();
  return math::Matrix3F::FromValues(
      target.region.width() * scale_x, 0, target.region.x() * scale_x,
      0, target.region.height() * scale_y, target.region.y() * scale_y,
      0, 0, 1);
}

}  // namespace

RenderTreeNodeVisitor::RenderTreeNodeVisitor(GraphicsState* graphics_state,
    DrawObjectManager* draw_object_manager,
    OffscreenTargetManager* offscreen_target_manager,
    const FallbackRasterizeFunction* fallback_rasterize)
    : graphics_state_(graphics_state),
      draw_object_manager_(draw_object_manager),
      offscreen_target_manager_(offscreen_target_manager),
      fallback_rasterize_(fallback_rasterize) {
  // Let the first draw object render in front of the clear depth.
  draw_state_.depth = GraphicsState::NextClosestDepth(draw_state_.depth);

  draw_state_.scissor.Intersect(graphics_state->GetViewport());
  draw_state_.scissor.Intersect(graphics_state->GetScissor());
}

void RenderTreeNodeVisitor::Visit(
    render_tree::CompositionNode* composition_node) {
  const render_tree::CompositionNode::Builder& data = composition_node->data();
  math::Matrix3F old_transform = draw_state_.transform;
  draw_state_.transform = draw_state_.transform *
      math::TranslateMatrix(data.offset().x(), data.offset().y());
  const render_tree::CompositionNode::Children& children =
      data.children();
  for (render_tree::CompositionNode::Children::const_iterator iter =
       children.begin(); iter != children.end(); ++iter) {
    (*iter)->Accept(this);
  }
  draw_state_.transform = old_transform;
}

void RenderTreeNodeVisitor::Visit(
    render_tree::MatrixTransform3DNode* transform_3d_node) {
  // TODO: Ignore the 3D transform matrix for now.
  transform_3d_node->data().source->Accept(this);
}

void RenderTreeNodeVisitor::Visit(
    render_tree::MatrixTransformNode* transform_node) {
  const render_tree::MatrixTransformNode::Builder& data =
      transform_node->data();
  math::Matrix3F old_transform = draw_state_.transform;
  draw_state_.transform = draw_state_.transform *
      data.transform;
  data.source->Accept(this);
  draw_state_.transform = old_transform;
}

void RenderTreeNodeVisitor::Visit(render_tree::FilterNode* filter_node) {
  const render_tree::FilterNode::Builder& data = filter_node->data();

  // If this is only a viewport filter w/o rounded edges, and the current
  // transform matrix keeps the filter as an orthogonal rect, then collapse
  // the node.
  if (data.viewport_filter &&
      !data.viewport_filter->has_rounded_corners() &&
      !data.opacity_filter &&
      !data.blur_filter &&
      !data.map_to_mesh_filter) {
    const math::Matrix3F& transform = draw_state_.transform;
    if (IsOnlyScaleAndTranslate(transform)) {
      // Transform local viewport to world viewport.
      const math::RectF& filter_viewport = data.viewport_filter->viewport();
      math::RectF transformed_viewport(
          filter_viewport.x() * transform(0, 0) + transform(0, 2),
          filter_viewport.y() * transform(1, 1) + transform(1, 2),
          filter_viewport.width() * transform(0, 0),
          filter_viewport.height() * transform(1, 1));
      // Ensure transformed viewport data is sane (in case global transform
      // flipped any axis).
      if (transformed_viewport.width() < 0) {
        transformed_viewport.set_x(transformed_viewport.right());
        transformed_viewport.set_width(-transformed_viewport.width());
      }
      if (transformed_viewport.height() < 0) {
        transformed_viewport.set_y(transformed_viewport.bottom());
        transformed_viewport.set_height(-transformed_viewport.height());
      }
      // Combine the new viewport filter with existing viewport filter.
      math::Rect old_scissor = draw_state_.scissor;
      draw_state_.scissor.Intersect(RoundRectFToInt(transformed_viewport));
      if (!draw_state_.scissor.IsEmpty()) {
        data.source->Accept(this);
      }
      draw_state_.scissor = old_scissor;
      return;
    }
  }

  // Handle opacity-only filter.
  if (data.opacity_filter &&
      !data.viewport_filter &&
      !data.blur_filter &&
      !data.map_to_mesh_filter) {
    int opacity = static_cast<int>(data.opacity_filter->opacity() * 255.0f);
    if (opacity <= 0) {
      // Totally transparent. Ignore the source.
      return;
    } else if (opacity >= 255) {
      // Totally opaque. Render like normal.
      data.source->Accept(this);
      return;
    } else if (common::utils::NodeCanRenderWithOpacity(data.source)) {
      float old_opacity = draw_state_.opacity;
      draw_state_.opacity *= data.opacity_filter->opacity();
      data.source->Accept(this);
      draw_state_.opacity = old_opacity;
      return;
    }
  }

  // Handle blur-only filter.
  if (data.blur_filter &&
      !data.viewport_filter &&
      !data.opacity_filter &&
      !data.map_to_mesh_filter) {
    if (data.blur_filter->blur_sigma() == 0.0f) {
      // Ignorable blur request. Render normally.
      data.source->Accept(this);
      return;
    }
  }

  // No filter.
  if (!data.opacity_filter &&
      !data.viewport_filter &&
      !data.blur_filter &&
      !data.map_to_mesh_filter) {
    data.source->Accept(this);
    return;
  }

  // Use the fallback rasterizer to handle everything else.
  FallbackRasterize(filter_node, DrawObjectManager::kOffscreenSkiaFilter);
}

void RenderTreeNodeVisitor::Visit(render_tree::ImageNode* image_node) {
  const render_tree::ImageNode::Builder& data = image_node->data();

  // The image node may contain nothing. For example, when it represents a video
  // element before any frame is decoded.
  if (!data.source) {
    return;
  }

  if (!IsVisible(image_node->GetBounds())) {
    return;
  }

  skia::Image* skia_image =
      base::polymorphic_downcast<skia::Image*>(data.source.get());
  bool clamp_texcoords = false;
  bool is_opaque = skia_image->IsOpaque() && draw_state_.opacity == 1.0f;

  // Ensure any required backend processing is done to create the necessary
  // GPU resource.
  skia_image->EnsureInitialized();

  // Calculate matrix to transform texture coordinates according to the local
  // transform.
  math::Matrix3F texcoord_transform(math::Matrix3F::Identity());
  if (IsOnlyScaleAndTranslate(data.local_transform)) {
    texcoord_transform(0, 0) = data.local_transform(0, 0) != 0 ?
        1.0f / data.local_transform(0, 0) : 0;
    texcoord_transform(1, 1) = data.local_transform(1, 1) != 0 ?
        1.0f / data.local_transform(1, 1) : 0;
    texcoord_transform(0, 2) = -texcoord_transform(0, 0) *
                               data.local_transform(0, 2);
    texcoord_transform(1, 2) = -texcoord_transform(1, 1) *
                               data.local_transform(1, 2);
    if (texcoord_transform(0, 0) < 1.0f || texcoord_transform(1, 1) < 1.0f) {
      // Edges may interpolate with texels outside the designated region.
      // Use a fragment shader that clamps the texture coordinates to prevent
      // that from happening.
      clamp_texcoords = true;
    }
  } else {
    texcoord_transform = data.local_transform.Inverse();
  }

  // Different shaders are used depending on whether the image has a single
  // plane or multiple planes.
  scoped_ptr<DrawObject> draw;
  DrawObjectManager::OnscreenType onscreen_type;

  if (skia_image->GetTypeId() == base::GetTypeId<skia::SinglePlaneImage>()) {
    skia::HardwareFrontendImage* hardware_image =
        base::polymorphic_downcast<skia::HardwareFrontendImage*>(skia_image);
    if (clamp_texcoords || !is_opaque) {
      onscreen_type = DrawObjectManager::kOnscreenRectColorTexture;
      draw.reset(new DrawRectColorTexture(graphics_state_, draw_state_,
          data.destination_rect,
          render_tree::ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f),
          hardware_image->GetTextureEGL(), texcoord_transform,
          clamp_texcoords));
    } else {
      onscreen_type = DrawObjectManager::kOnscreenRectTexture;
      draw.reset(new DrawRectTexture(graphics_state_, draw_state_,
          data.destination_rect, hardware_image->GetTextureEGL(),
          texcoord_transform));
    }
  } else if (skia_image->GetTypeId() ==
             base::GetTypeId<skia::MultiPlaneImage>()) {
    FallbackRasterize(image_node,
                      DrawObjectManager::kOffscreenSkiaMultiPlaneImage);
    return;
  } else {
    NOTREACHED();
    return;
  }

  if (is_opaque) {
    AddOpaqueDraw(draw.Pass(), onscreen_type,
        DrawObjectManager::kOffscreenNone);
  } else {
    AddTransparentDraw(draw.Pass(), onscreen_type,
        DrawObjectManager::kOffscreenNone, image_node->GetBounds());
  }
}

void RenderTreeNodeVisitor::Visit(
    render_tree::PunchThroughVideoNode* video_node) {
  if (!IsVisible(video_node->GetBounds())) {
    return;
  }

  const render_tree::PunchThroughVideoNode::Builder& data = video_node->data();
  math::RectF mapped_rect = draw_state_.transform.MapRect(data.rect);
  data.set_bounds_cb.Run(
      math::Rect(static_cast<int>(mapped_rect.x()),
                 static_cast<int>(mapped_rect.y()),
                 static_cast<int>(mapped_rect.width()),
                 static_cast<int>(mapped_rect.height())));

  scoped_ptr<DrawObject> draw(new DrawPolyColor(graphics_state_,
      draw_state_, data.rect, render_tree::ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f)));
  AddOpaqueDraw(draw.Pass(), DrawObjectManager::kOnscreenPolyColor,
      DrawObjectManager::kOffscreenNone);
}

void RenderTreeNodeVisitor::Visit(render_tree::RectNode* rect_node) {
  if (!IsVisible(rect_node->GetBounds())) {
    return;
  }

  const render_tree::RectNode::Builder& data = rect_node->data();
  const scoped_ptr<render_tree::Brush>& brush = data.background_brush;

  // Only solid color brushes are supported at this time.
  const bool brush_supported = !brush ||
      brush->GetTypeId() == base::GetTypeId<render_tree::SolidColorBrush>() ||
      brush->GetTypeId() == base::GetTypeId<render_tree::LinearGradientBrush>();

  // Borders are not supported natively by this rasterizer at this time. The
  // difficulty lies in getting anti-aliased borders and minimizing state
  // switches (due to anti-aliased borders requiring transparency). However,
  // by using the fallback rasterizer, both can be accomplished -- sort to
  // minimize state switches while rendering anti-aliased borders to the
  // offscreen target, then use a single shader to render those.
  const bool border_supported = !data.border;

  if (data.rounded_corners) {
    FallbackRasterize(rect_node, DrawObjectManager::kOffscreenSkiaRectRounded);
  } else if (!brush_supported) {
    FallbackRasterize(rect_node, DrawObjectManager::kOffscreenSkiaRectBrush);
  } else if (!border_supported) {
    FallbackRasterize(rect_node, DrawObjectManager::kOffscreenSkiaRectBorder);
  } else {
    DCHECK(!data.border);
    const math::RectF& content_rect(data.rect);

    // Handle drawing the content.
    if (brush) {
      base::TypeId brush_type = brush->GetTypeId();
      if (brush_type == base::GetTypeId<render_tree::SolidColorBrush>()) {
        const render_tree::SolidColorBrush* solid_brush =
            base::polymorphic_downcast<const render_tree::SolidColorBrush*>
                (brush.get());
        const render_tree::ColorRGBA& brush_color(solid_brush->color());
        render_tree::ColorRGBA content_color(
            brush_color.r() * brush_color.a(),
            brush_color.g() * brush_color.a(),
            brush_color.b() * brush_color.a(),
            brush_color.a());
        scoped_ptr<DrawObject> draw(new DrawPolyColor(graphics_state_,
            draw_state_, content_rect, content_color));
        if (draw_state_.opacity * content_color.a() == 1.0f) {
          AddOpaqueDraw(draw.Pass(), DrawObjectManager::kOnscreenPolyColor,
              DrawObjectManager::kOffscreenNone);
        } else {
          AddTransparentDraw(draw.Pass(), DrawObjectManager::kOnscreenPolyColor,
              DrawObjectManager::kOffscreenNone, rect_node->GetBounds());
        }
      } else {
        const render_tree::LinearGradientBrush* linear_brush =
            base::polymorphic_downcast<const render_tree::LinearGradientBrush*>
                (brush.get());
        scoped_ptr<DrawObject> draw(new DrawRectLinearGradient(graphics_state_,
            draw_state_, content_rect, *linear_brush));
        // The draw may use transparent colors or a depth stencil (but only
        // the inclusive one, so only one depth value is needed), so make it
        // a transparent draw.
        AddTransparentDraw(draw.Pass(), DrawObjectManager::kOnscreenPolyColor,
            DrawObjectManager::kOffscreenNone, rect_node->GetBounds());
      }
    }
  }
}

void RenderTreeNodeVisitor::Visit(render_tree::RectShadowNode* shadow_node) {
  math::RectF node_bounds(shadow_node->GetBounds());
  if (!IsVisible(node_bounds)) {
    return;
  }

  const render_tree::RectShadowNode::Builder& data = shadow_node->data();
  if (data.rounded_corners) {
    FallbackRasterize(shadow_node, DrawObjectManager::kOffscreenSkiaShadow);
    return;
  }

  scoped_ptr<DrawObject> draw;
  render_tree::ColorRGBA shadow_color(
      data.shadow.color.r() * data.shadow.color.a(),
      data.shadow.color.g() * data.shadow.color.a(),
      data.shadow.color.b() * data.shadow.color.a(),
      data.shadow.color.a());
  DrawObjectManager::OnscreenType onscreen_type =
      DrawObjectManager::kOnscreenRectShadow;

  math::RectF spread_rect(data.rect);
  spread_rect.Offset(data.shadow.offset);
  if (data.inset) {
    // data.rect is outermost.
    // spread_rect is in the middle.
    // blur_rect is innermost.
    spread_rect.Inset(data.spread, data.spread);
    spread_rect.Intersect(data.rect);
    if (spread_rect.IsEmpty()) {
      // Spread covers the whole data.rect.
      spread_rect.set_origin(data.rect.CenterPoint());
      spread_rect.set_size(math::SizeF());
    }
    if (!spread_rect.IsEmpty() && data.shadow.blur_sigma > 0.0f) {
      math::RectF blur_rect(spread_rect);
      math::Vector2dF blur_extent(data.shadow.BlurExtent());
      blur_rect.Inset(blur_extent.x(), blur_extent.y());
      blur_rect.Intersect(spread_rect);
      if (blur_rect.IsEmpty()) {
        // Blur covers all of spread.
        blur_rect.set_origin(spread_rect.CenterPoint());
        blur_rect.set_size(math::SizeF());
      }
      draw.reset(new DrawRectShadowBlur(graphics_state_, draw_state_,
          blur_rect, data.rect, spread_rect, shadow_color, math::RectF(),
          data.shadow.blur_sigma, data.inset));
      onscreen_type = DrawObjectManager::kOnscreenRectShadowBlur;
    } else {
      draw.reset(new DrawRectShadowSpread(graphics_state_, draw_state_,
          spread_rect, data.rect, shadow_color, data.rect, math::RectF()));
    }
  } else {
    // blur_rect is outermost.
    // spread_rect is in the middle (barring negative |spread| values).
    // data.rect is innermost (though it may not overlap due to offset).
    spread_rect.Outset(data.spread, data.spread);
    if (spread_rect.IsEmpty()) {
      // Negative spread shenanigans! Nothing to draw.
      return;
    }
    math::RectF blur_rect(spread_rect);
    if (data.shadow.blur_sigma > 0.0f) {
      math::Vector2dF blur_extent(data.shadow.BlurExtent());
      blur_rect.Outset(blur_extent.x(), blur_extent.y());
      draw.reset(new DrawRectShadowBlur(graphics_state_, draw_state_,
          data.rect, blur_rect, spread_rect, shadow_color, data.rect,
          data.shadow.blur_sigma, data.inset));
      onscreen_type = DrawObjectManager::kOnscreenRectShadowBlur;
    } else {
      draw.reset(new DrawRectShadowSpread(graphics_state_, draw_state_,
          data.rect, spread_rect, shadow_color, spread_rect, data.rect));
    }
    node_bounds.Union(blur_rect);
  }

  // Include or exclude scissor will touch these pixels.
  node_bounds.Union(data.rect);

  // Since the depth buffer is polluted to create a stencil for pixels to be
  // modified by the shadow, this draw must occur during the transparency
  // pass. During this pass, all subsequent draws are guaranteed to be closer
  // (i.e. pass the depth test) than pixels modified by previous transparency
  // draws.
  AddTransparentDraw(draw.Pass(), onscreen_type,
      DrawObjectManager::kOffscreenNone, node_bounds);

  // Since the box shadow draw objects use the depth stencil object, two depth
  // values were used. So skip an additional depth value.
  draw_state_.depth = GraphicsState::NextClosestDepth(draw_state_.depth);
}

void RenderTreeNodeVisitor::Visit(render_tree::TextNode* text_node) {
  if (!IsVisible(text_node->GetBounds())) {
    return;
  }

  FallbackRasterize(text_node, DrawObjectManager::kOffscreenSkiaText);
}

void RenderTreeNodeVisitor::FallbackRasterize(
    scoped_refptr<render_tree::Node> node,
    DrawObjectManager::OffscreenType offscreen_type) {
  DCHECK_NE(offscreen_type, DrawObjectManager::kOffscreenNone);

  math::RectF node_bounds(node->GetBounds());
  math::RectF mapped_bounds(draw_state_.transform.MapRect(node_bounds));
  if (mapped_bounds.IsEmpty()) {
    return;
  }

  // Use the fallback rasterizer to render the tree. In order to preserve
  // sharpness, let the fallback rasterizer handle the current transform.
  math::Matrix3F old_transform = draw_state_.transform;
  draw_state_.transform = math::Matrix3F::Identity();

  // Request a slightly larger render target than the calculated bounds. The
  // fallback rasterizer may use an extra pixel along the edge of anti-aliased
  // objects.
  const float kBorderWidth = 1.0f;

  // The render target cache keys off the render_tree Node and target size.
  // Since the size is rounded, it is possible to be a fraction of a pixel
  // off. However, this in turn allows for a cache hit for "close-enough"
  // renderings. To minimize offset errors, use the nearest full pixel offset.
  const float kFractionPad = 1.0f;
  float offset_x = std::floor(mapped_bounds.x() + 0.5f);
  float offset_y = std::floor(mapped_bounds.y() + 0.5f);
  math::PointF content_offset(
      // Shift contents towards the origin of the render target.
      kBorderWidth + kFractionPad - offset_x,
      kBorderWidth + kFractionPad - offset_y);
  math::SizeF content_size(
      std::ceil(mapped_bounds.width() + 2.0f * kBorderWidth + kFractionPad),
      std::ceil(mapped_bounds.height() + 2.0f * kBorderWidth + kFractionPad));
  OffscreenTargetManager::TargetInfo target_info;
  bool is_cached = offscreen_target_manager_->GetCachedOffscreenTarget(node,
      content_size, &target_info);
  if (!is_cached) {
    offscreen_target_manager_->AllocateOffscreenTarget(node,
        content_size, &target_info);
  }

  // If the render target is the scratch surface, then just render what fits
  // onscreen for better performance.
  if (target_info.is_scratch_surface) {
    mapped_bounds.Outset(kBorderWidth, kBorderWidth);
    mapped_bounds.Intersect(draw_state_.scissor);
    if (mapped_bounds.IsEmpty()) {
      return;
    }
    float left = std::floor(mapped_bounds.x());
    float right = std::ceil(mapped_bounds.right());
    float top = std::floor(mapped_bounds.y());
    float bottom = std::ceil(mapped_bounds.bottom());
    content_offset.SetPoint(-left, -top);
    content_size.SetSize(right - left, bottom - top);
  }

  // The returned target may be larger than actually needed. Clamp to just the
  // needed size.
  DCHECK_LE(content_size.width(), target_info.region.width());
  DCHECK_LE(content_size.height(), target_info.region.height());
  target_info.region.set_size(content_size);
  math::RectF draw_rect(-content_offset.x(), -content_offset.y(),
      content_size.width(), content_size.height());

  // Setup draw callbacks as needed.
  base::Closure draw_offscreen;
  base::Closure draw_onscreen;
  if (!is_cached) {
    // Pre-translate the contents so it starts near the origin.
    math::Matrix3F content_transform(old_transform);
    content_transform(0, 2) += content_offset.x();
    content_transform(1, 2) += content_offset.y();

    if (target_info.is_scratch_surface) {
      draw_onscreen = base::Bind(*fallback_rasterize_,
          scoped_refptr<render_tree::Node>(node), content_transform,
          target_info);
    } else {
      draw_offscreen = base::Bind(*fallback_rasterize_,
          scoped_refptr<render_tree::Node>(node), content_transform,
          target_info);
    }
  }

  // Create the appropriate draw object to call the draw callback, then render
  // its results onscreen.
  backend::TextureEGL* texture = target_info.framebuffer->GetColorTexture();
  math::Matrix3F texcoord_transform = GetTexcoordTransform(target_info);
  if (draw_state_.opacity == 1.0f) {
    scoped_ptr<DrawObject> draw(new DrawRectTexture(graphics_state_,
        draw_state_, draw_rect, texture, texcoord_transform,
        draw_offscreen, draw_onscreen));
    AddTransparentDraw(draw.Pass(), DrawObjectManager::kOnscreenRectTexture,
        offscreen_type, draw_rect);
  } else {
    scoped_ptr<DrawObject> draw(new DrawRectColorTexture(graphics_state_,
        draw_state_, draw_rect, render_tree::ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f),
        texture, texcoord_transform, draw_offscreen, draw_onscreen));
    AddTransparentDraw(draw.Pass(),
        DrawObjectManager::kOnscreenRectColorTexture, offscreen_type,
        draw_rect);
  }

  draw_state_.transform = old_transform;
}

bool RenderTreeNodeVisitor::IsVisible(const math::RectF& bounds) {
  math::RectF intersection = IntersectRects(
      draw_state_.transform.MapRect(bounds), draw_state_.scissor);
  return !intersection.IsEmpty();
}

void RenderTreeNodeVisitor::AddOpaqueDraw(scoped_ptr<DrawObject> object,
    DrawObjectManager::OnscreenType onscreen_type,
    DrawObjectManager::OffscreenType offscreen_type) {
  draw_object_manager_->AddOpaqueDraw(object.Pass(), onscreen_type,
      offscreen_type);
  draw_state_.depth = GraphicsState::NextClosestDepth(draw_state_.depth);
}

void RenderTreeNodeVisitor::AddTransparentDraw(scoped_ptr<DrawObject> object,
    DrawObjectManager::OnscreenType onscreen_type,
    DrawObjectManager::OffscreenType offscreen_type,
    const math::RectF& local_bounds) {
  draw_object_manager_->AddTransparentDraw(object.Pass(), onscreen_type,
      offscreen_type, draw_state_.transform.MapRect(local_bounds));
  draw_state_.depth = GraphicsState::NextClosestDepth(draw_state_.depth);
}

}  // namespace egl
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
