// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/output/delegating_renderer.h"

#include <set>
#include <string>
#include <vector>

#include "base/debug/trace_event.h"
#include "cc/output/compositor_frame_ack.h"
#include "cc/output/context_provider.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/render_pass.h"
#include "cc/resources/resource_provider.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"


namespace cc {

scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create(
    RendererClient* client,
    const RendererSettings* settings,
    OutputSurface* output_surface,
    ResourceProvider* resource_provider) {
  return make_scoped_ptr(new DelegatingRenderer(
      client, settings, output_surface, resource_provider));
}

DelegatingRenderer::DelegatingRenderer(RendererClient* client,
                                       const RendererSettings* settings,
                                       OutputSurface* output_surface,
                                       ResourceProvider* resource_provider)
    : Renderer(client, settings),
      output_surface_(output_surface),
      resource_provider_(resource_provider) {
  DCHECK(resource_provider_);

  capabilities_.using_partial_swap = false;
  capabilities_.max_texture_size = resource_provider_->max_texture_size();
  capabilities_.best_texture_format = resource_provider_->best_texture_format();
  capabilities_.allow_partial_texture_updates = false;

  if (!output_surface_->context_provider()) {
    capabilities_.using_shared_memory_resources = true;
  } else {
    const ContextProvider::Capabilities& caps =
        output_surface_->context_provider()->ContextCapabilities();

    DCHECK(!caps.gpu.iosurface || caps.gpu.texture_rectangle);

    capabilities_.using_egl_image = caps.gpu.egl_image_external;
    capabilities_.using_image = caps.gpu.image;

    capabilities_.allow_rasterize_on_demand = false;
  }
}

DelegatingRenderer::~DelegatingRenderer() {}

const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const {
  return capabilities_;
}

static ResourceProvider::ResourceId AppendToArray(
    ResourceProvider::ResourceIdArray* array,
    ResourceProvider::ResourceId id) {
  array->push_back(id);
  return id;
}

void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
                                   float device_scale_factor,
                                   const gfx::Rect& device_viewport_rect,
                                   const gfx::Rect& device_clip_rect,
                                   bool disable_picture_quad_image_filtering) {
  TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");

  DCHECK(!delegated_frame_data_);

  delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData);
  DelegatedFrameData& out_data = *delegated_frame_data_;
  out_data.device_scale_factor = device_scale_factor;
  // Move the render passes and resources into the |out_frame|.
  out_data.render_pass_list.swap(*render_passes_in_draw_order);

  // Collect all resource ids in the render passes into a ResourceIdArray.
  ResourceProvider::ResourceIdArray resources;
  DrawQuad::ResourceIteratorCallback append_to_array =
      base::Bind(&AppendToArray, &resources);
  for (const auto& render_pass : out_data.render_pass_list) {
    for (const auto& quad : render_pass->quad_list)
      quad->IterateResources(append_to_array);
  }
  resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
}

void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
  TRACE_EVENT0("cc,benchmark", "DelegatingRenderer::SwapBuffers");
  CompositorFrame compositor_frame;
  compositor_frame.metadata = metadata;
  compositor_frame.delegated_frame_data = delegated_frame_data_.Pass();
  output_surface_->SwapBuffers(&compositor_frame);
}

void DelegatingRenderer::ReceiveSwapBuffersAck(
    const CompositorFrameAck& ack) {
  resource_provider_->ReceiveReturnsFromParent(ack.resources);
}

void DelegatingRenderer::DidChangeVisibility() {
  ContextProvider* context_provider = output_surface_->context_provider();
  if (!visible()) {
    TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
    resource_provider_->ReleaseCachedData();
    if (context_provider) {
      context_provider->DeleteCachedResources();
      context_provider->ContextGL()->Flush();
    }
  }
  // We loop visibility to the GPU process, since that's what manages memory.
  // That will allow it to feed us with memory allocations that we can act
  // upon.
  if (context_provider)
    context_provider->ContextSupport()->SetSurfaceVisible(visible());
}

}  // namespace cc
