blob: f4b711c3ae0fd7e482741bbfc4b406e20979fc3f [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GFX_COMPOSITOR_COMPOSITOR_H_
#define UI_GFX_COMPOSITOR_COMPOSITOR_H_
#pragma once
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebLayer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebLayerTreeView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebLayerTreeViewClient.h"
#include "ui/gfx/compositor/compositor_export.h"
#include "ui/gfx/gl/gl_share_group.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
#include "ui/gfx/transform.h"
class SkBitmap;
namespace gfx {
class GLContext;
class GLSurface;
class GLShareGroup;
class Point;
class Rect;
}
namespace ui {
class Compositor;
class CompositorObserver;
class Layer;
// This class abstracts the creation of the 3D context for the compositor. It is
// a global object.
class COMPOSITOR_EXPORT ContextFactory {
public:
virtual ~ContextFactory() { }
// Gets the global instance.
static ContextFactory* GetInstance();
// Sets the global instance. Caller keeps ownership.
// If this function isn't called (for tests), a "default" factory will be
// created on the first call of GetInstance.
static void SetInstance(ContextFactory* instance);
// Creates a context for given compositor. The factory may keep per-compositor
// data (e.g. a shared context), that needs to be cleaned up by calling
// RemoveCompositor when the compositor gets destroyed.
virtual WebKit::WebGraphicsContext3D* CreateContext(
Compositor* compositor) = 0;
// Destroys per-compositor data.
virtual void RemoveCompositor(Compositor* compositor) = 0;
};
// The default factory that creates in-process contexts.
class COMPOSITOR_EXPORT DefaultContextFactory : public ContextFactory {
public:
DefaultContextFactory();
virtual ~DefaultContextFactory();
// ContextFactory implementation
virtual WebKit::WebGraphicsContext3D* CreateContext(
Compositor* compositor) OVERRIDE;
virtual void RemoveCompositor(Compositor* compositor) OVERRIDE;
bool Initialize();
void set_share_group(gfx::GLShareGroup* share_group) {
share_group_ = share_group;
}
private:
scoped_refptr<gfx::GLShareGroup> share_group_;
DISALLOW_COPY_AND_ASSIGN(DefaultContextFactory);
};
// Texture provide an abstraction over the external texture that can be passed
// to a layer.
class COMPOSITOR_EXPORT Texture : public base::RefCounted<Texture> {
public:
Texture(bool flipped, const gfx::Size& size);
virtual ~Texture();
unsigned int texture_id() const { return texture_id_; }
void set_texture_id(unsigned int id) { texture_id_ = id; }
bool flipped() const { return flipped_; }
gfx::Size size() const { return size_; }
private:
unsigned int texture_id_;
bool flipped_;
gfx::Size size_;
DISALLOW_COPY_AND_ASSIGN(Texture);
};
// An interface to allow the compositor to communicate with its owner.
class COMPOSITOR_EXPORT CompositorDelegate {
public:
// Requests the owner to schedule a redraw of the layer tree.
virtual void ScheduleDraw() = 0;
protected:
virtual ~CompositorDelegate() {}
};
// Compositor object to take care of GPU painting.
// A Browser compositor object is responsible for generating the final
// displayable form of pixels comprising a single widget's contents. It draws an
// appropriately transformed texture for each transformed view in the widget's
// view hierarchy.
class COMPOSITOR_EXPORT Compositor
: NON_EXPORTED_BASE(public WebKit::WebLayerTreeViewClient) {
public:
Compositor(CompositorDelegate* delegate,
gfx::AcceleratedWidget widget,
const gfx::Size& size);
virtual ~Compositor();
static void Initialize(bool useThread);
static void Terminate();
// Schedules a redraw of the layer tree associated with this compositor.
void ScheduleDraw();
// Sets the root of the layer tree drawn by this Compositor. The root layer
// must have no parent. The compositor's root layer is reset if the root layer
// is destroyed. NULL can be passed to reset the root layer, in which case the
// compositor will stop drawing anything.
// The Compositor does not own the root layer.
const Layer* root_layer() const { return root_layer_; }
Layer* root_layer() { return root_layer_; }
void SetRootLayer(Layer* root_layer);
// Draws the scene created by the layer tree and any visual effects. If
// |force_clear| is true, this will cause the compositor to clear before
// compositing.
void Draw(bool force_clear);
// Where possible, draws are scissored to a damage region calculated from
// changes to layer properties. This bypasses that and indicates that
// the whole frame needs to be drawn.
void ScheduleFullDraw();
// Reads the region |bounds| of the contents of the last rendered frame
// into the given bitmap.
// Returns false if the pixels could not be read.
bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds);
// Notifies the compositor that the size of the widget that it is
// drawing to has changed.
void WidgetSizeChanged(const gfx::Size& size);
// Returns the size of the widget that is being drawn to.
const gfx::Size& size() const { return size_; }
// Returns the widget for this compositor.
gfx::AcceleratedWidget widget() const { return widget_; }
// Compositor does not own observers. It is the responsibility of the
// observer to remove itself when it is done observing.
void AddObserver(CompositorObserver* observer);
void RemoveObserver(CompositorObserver* observer);
bool HasObserver(CompositorObserver* observer);
// Internal functions, called back by command-buffer contexts on swap buffer
// events.
// Signals swap has been posted.
void OnSwapBuffersPosted();
// Signals swap has completed.
void OnSwapBuffersComplete();
// Signals swap has aborted (e.g. lost context).
void OnSwapBuffersAborted();
// WebLayerTreeViewClient implementation.
virtual void updateAnimations(double frameBeginTime);
virtual void layout();
virtual void applyScrollAndScale(const WebKit::WebSize& scrollDelta,
float scaleFactor);
virtual WebKit::WebGraphicsContext3D* createContext3D();
virtual void didRebindGraphicsContext(bool success);
virtual void didCommitAndDrawFrame();
virtual void didCompleteSwapBuffers();
virtual void scheduleComposite();
private:
// When reading back pixel data we often get RGBA rather than BGRA pixels and
// and the image often needs to be flipped vertically.
static void SwizzleRGBAToBGRAAndFlip(unsigned char* pixels,
const gfx::Size& image_size);
// Notifies the compositor that compositing is complete.
void NotifyEnd();
CompositorDelegate* delegate_;
gfx::Size size_;
// The root of the Layer tree drawn by this compositor.
Layer* root_layer_;
ObserverList<CompositorObserver> observer_list_;
gfx::AcceleratedWidget widget_;
WebKit::WebLayer root_web_layer_;
WebKit::WebLayerTreeView host_;
// This is set to true when the swap buffers has been posted and we're waiting
// for completion.
bool swap_posted_;
friend class base::RefCounted<Compositor>;
};
} // namespace ui
#endif // UI_GFX_COMPOSITOR_COMPOSITOR_H_