Improve off-screen rendering behavior (issue #1257).
- The |dirtyRects| argument to CefRenderHandler::OnPaint is now a single rectangle representing the union of all dirty rectangles since the last frame was generated. In most cases this rectangle will be smaller than the view (frame) size. - cefclient: Use a ScopedGLContext class on all platforms to manage the current GL context and avoid GL state leaks. - cefclient: Add debug checks in ClientOSRenderer for GL errors and fix some errors that were discovered. - cefclient: Add a new `--show-update-rect` command-line flag that provides visualization of the update rectangle by drawing a red border around it for each frame. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1945 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
cbae1994ae
commit
b12e172af0
|
@ -274,13 +274,21 @@ void CefRenderWidgetHostViewOSR::OnSwapCompositorFrame(
|
|||
}
|
||||
|
||||
if (frame->delegated_frame_data) {
|
||||
// Determine the damage rectangle for the current frame. This is the same
|
||||
// calculation that SwapDelegatedFrame uses.
|
||||
cc::RenderPass* root_pass =
|
||||
frame->delegated_frame_data->render_pass_list.back();
|
||||
gfx::Size frame_size = root_pass->output_rect.size();
|
||||
gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect);
|
||||
damage_rect.Intersect(gfx::Rect(frame_size));
|
||||
|
||||
delegated_frame_host_->SwapDelegatedFrame(
|
||||
output_surface_id,
|
||||
frame->delegated_frame_data.Pass(),
|
||||
frame->metadata.device_scale_factor,
|
||||
frame->metadata.latency_info);
|
||||
|
||||
GenerateFrame(true);
|
||||
GenerateFrame(true, damage_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -700,7 +708,7 @@ void CefRenderWidgetHostViewOSR::Invalidate(
|
|||
return;
|
||||
}
|
||||
|
||||
GenerateFrame(true);
|
||||
GenerateFrame(true, root_layer_->bounds());
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::SendKeyEvent(
|
||||
|
@ -829,7 +837,9 @@ void CefRenderWidgetHostViewOSR::ResizeRootLayer() {
|
|||
compositor_->SetScaleAndSize(CurrentDeviceScaleFactor(), size);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::GenerateFrame(bool force_frame) {
|
||||
void CefRenderWidgetHostViewOSR::GenerateFrame(
|
||||
bool force_frame,
|
||||
const gfx::Rect& damage_rect) {
|
||||
if (force_frame && !frame_pending_)
|
||||
frame_pending_ = true;
|
||||
|
||||
|
@ -837,6 +847,10 @@ void CefRenderWidgetHostViewOSR::GenerateFrame(bool force_frame) {
|
|||
if (!frame_pending_)
|
||||
return;
|
||||
|
||||
// Keep track of |damage_rect| for when the next frame is generated.
|
||||
if (!damage_rect.IsEmpty())
|
||||
pending_damage_rect_.Union(damage_rect);
|
||||
|
||||
// Don't attempt to generate a frame while one is currently in-progress.
|
||||
if (frame_in_progress_)
|
||||
return;
|
||||
|
@ -864,13 +878,17 @@ void CefRenderWidgetHostViewOSR::InternalGenerateFrame() {
|
|||
if (!render_widget_host_)
|
||||
return;
|
||||
|
||||
const gfx::Rect damage_rect = pending_damage_rect_;
|
||||
pending_damage_rect_.SetRect(0, 0, 0, 0);
|
||||
|
||||
// The below code is similar in functionality to
|
||||
// DelegatedFrameHost::CopyFromCompositingSurface but we reuse the same
|
||||
// SkBitmap in the GPU codepath and avoid scaling where possible.
|
||||
scoped_ptr<cc::CopyOutputRequest> request =
|
||||
cc::CopyOutputRequest::CreateRequest(base::Bind(
|
||||
&CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceHasResult,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
damage_rect));
|
||||
|
||||
const gfx::Rect& src_subrect_in_pixel =
|
||||
content::ConvertRectToPixel(CurrentDeviceScaleFactor(),
|
||||
|
@ -880,27 +898,30 @@ void CefRenderWidgetHostViewOSR::InternalGenerateFrame() {
|
|||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceHasResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<cc::CopyOutputResult> result) {
|
||||
if (result->IsEmpty() || result->size().IsEmpty() || !render_widget_host_) {
|
||||
OnFrameCaptureFailure();
|
||||
OnFrameCaptureFailure(damage_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result->HasTexture()) {
|
||||
PrepareTextureCopyOutputResult(result.Pass());
|
||||
PrepareTextureCopyOutputResult(damage_rect, result.Pass());
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK(result->HasBitmap());
|
||||
PrepareBitmapCopyOutputResult(result.Pass());
|
||||
PrepareBitmapCopyOutputResult(damage_rect, result.Pass());
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::PrepareTextureCopyOutputResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<cc::CopyOutputResult> result) {
|
||||
DCHECK(result->HasTexture());
|
||||
base::ScopedClosureRunner scoped_callback_runner(
|
||||
base::Bind(&CefRenderWidgetHostViewOSR::OnFrameCaptureFailure,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
damage_rect));
|
||||
|
||||
const gfx::Size& result_size = result->size();
|
||||
SkIRect bitmap_size;
|
||||
|
@ -950,6 +971,7 @@ void CefRenderWidgetHostViewOSR::PrepareTextureCopyOutputResult(
|
|||
&CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceFinishedProxy,
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
base::Passed(&release_callback),
|
||||
damage_rect,
|
||||
base::Passed(&bitmap_),
|
||||
base::Passed(&bitmap_pixels_lock)),
|
||||
content::GLHelper::SCALER_QUALITY_FAST);
|
||||
|
@ -959,6 +981,7 @@ void CefRenderWidgetHostViewOSR::PrepareTextureCopyOutputResult(
|
|||
void CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceFinishedProxy(
|
||||
base::WeakPtr<CefRenderWidgetHostViewOSR> view,
|
||||
scoped_ptr<cc::SingleReleaseCallback> release_callback,
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<SkBitmap> bitmap,
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
|
||||
bool result) {
|
||||
|
@ -974,7 +997,7 @@ void CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceFinishedProxy(
|
|||
|
||||
if (view) {
|
||||
view->CopyFromCompositingSurfaceFinished(
|
||||
bitmap.Pass(), bitmap_pixels_lock.Pass(), result);
|
||||
damage_rect, bitmap.Pass(), bitmap_pixels_lock.Pass(), result);
|
||||
} else {
|
||||
bitmap_pixels_lock.reset();
|
||||
bitmap.reset();
|
||||
|
@ -982,6 +1005,7 @@ void CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceFinishedProxy(
|
|||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceFinished(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<SkBitmap> bitmap,
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
|
||||
bool result) {
|
||||
|
@ -990,14 +1014,15 @@ void CefRenderWidgetHostViewOSR::CopyFromCompositingSurfaceFinished(
|
|||
bitmap_ = bitmap.Pass();
|
||||
|
||||
if (result) {
|
||||
OnFrameCaptureSuccess(*bitmap_, bitmap_pixels_lock.Pass());
|
||||
OnFrameCaptureSuccess(damage_rect, *bitmap_, bitmap_pixels_lock.Pass());
|
||||
} else {
|
||||
bitmap_pixels_lock.reset();
|
||||
OnFrameCaptureFailure();
|
||||
OnFrameCaptureFailure(damage_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::PrepareBitmapCopyOutputResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<cc::CopyOutputResult> result) {
|
||||
DCHECK(result->HasBitmap());
|
||||
scoped_ptr<SkBitmap> source = result->TakeBitmap();
|
||||
|
@ -1005,33 +1030,39 @@ void CefRenderWidgetHostViewOSR::PrepareBitmapCopyOutputResult(
|
|||
if (source) {
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
|
||||
new SkAutoLockPixels(*source));
|
||||
OnFrameCaptureSuccess(*source, bitmap_pixels_lock.Pass());
|
||||
OnFrameCaptureSuccess(damage_rect, *source, bitmap_pixels_lock.Pass());
|
||||
} else {
|
||||
OnFrameCaptureFailure();
|
||||
OnFrameCaptureFailure(damage_rect);
|
||||
}
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::OnFrameCaptureFailure() {
|
||||
void CefRenderWidgetHostViewOSR::OnFrameCaptureFailure(
|
||||
const gfx::Rect& damage_rect) {
|
||||
// Retry with the same |damage_rect|.
|
||||
pending_damage_rect_.Union(damage_rect);
|
||||
|
||||
const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit);
|
||||
OnFrameCaptureCompletion(force_frame);
|
||||
}
|
||||
|
||||
void CefRenderWidgetHostViewOSR::OnFrameCaptureSuccess(
|
||||
const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap,
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock) {
|
||||
SkRect bounds;
|
||||
bitmap.getBounds(&bounds);
|
||||
gfx::Rect rect_in_bitmap(0, 0, bitmap.width(), bitmap.height());
|
||||
rect_in_bitmap.Intersect(damage_rect);
|
||||
|
||||
CefRenderHandler::RectList rcList;
|
||||
rcList.push_back(CefRect(0, 0, bounds.width(), bounds.height()));
|
||||
rcList.push_back(CefRect(rect_in_bitmap.x(), rect_in_bitmap.y(),
|
||||
rect_in_bitmap.width(), rect_in_bitmap.height()));
|
||||
|
||||
browser_impl_->GetClient()->GetRenderHandler()->OnPaint(
|
||||
browser_impl_.get(),
|
||||
IsPopupWidget() ? PET_POPUP : PET_VIEW,
|
||||
rcList,
|
||||
bitmap.getPixels(),
|
||||
bounds.width(),
|
||||
bounds.height());
|
||||
bitmap.width(),
|
||||
bitmap.height());
|
||||
|
||||
bitmap_pixels_lock.reset();
|
||||
|
||||
|
@ -1050,7 +1081,9 @@ void CefRenderWidgetHostViewOSR::OnFrameCaptureCompletion(bool force_frame) {
|
|||
// Generate the pending frame now.
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefRenderWidgetHostViewOSR::GenerateFrame,
|
||||
weak_ptr_factory_.GetWeakPtr(), force_frame));
|
||||
weak_ptr_factory_.GetWeakPtr(),
|
||||
force_frame,
|
||||
gfx::Rect()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -249,26 +249,32 @@ class CefRenderWidgetHostViewOSR
|
|||
|
||||
// Implementation based on RendererOverridesHandler::InnerSwapCompositorFrame
|
||||
// and DelegatedFrameHost::CopyFromCompositingSurface.
|
||||
void GenerateFrame(bool force_frame);
|
||||
void GenerateFrame(bool force_frame, const gfx::Rect& damage_rect);
|
||||
void InternalGenerateFrame();
|
||||
void CopyFromCompositingSurfaceHasResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<cc::CopyOutputResult> result);
|
||||
void PrepareTextureCopyOutputResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<cc::CopyOutputResult> result);
|
||||
static void CopyFromCompositingSurfaceFinishedProxy(
|
||||
base::WeakPtr<CefRenderWidgetHostViewOSR> view,
|
||||
scoped_ptr<cc::SingleReleaseCallback> release_callback,
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<SkBitmap> bitmap,
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
|
||||
bool result);
|
||||
void CopyFromCompositingSurfaceFinished(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<SkBitmap> bitmap,
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
|
||||
bool result);
|
||||
void PrepareBitmapCopyOutputResult(
|
||||
const gfx::Rect& damage_rect,
|
||||
scoped_ptr<cc::CopyOutputResult> result);
|
||||
void OnFrameCaptureFailure();
|
||||
void OnFrameCaptureFailure(const gfx::Rect& damage_rect);
|
||||
void OnFrameCaptureSuccess(
|
||||
const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap,
|
||||
scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock);
|
||||
void OnFrameCaptureCompletion(bool force_frame);
|
||||
|
@ -323,6 +329,7 @@ class CefRenderWidgetHostViewOSR
|
|||
bool frame_in_progress_;
|
||||
int frame_retry_count_;
|
||||
scoped_ptr<SkBitmap> bitmap_;
|
||||
gfx::Rect pending_damage_rect_;
|
||||
|
||||
bool hold_resize_;
|
||||
bool pending_resize_;
|
||||
|
|
|
@ -545,12 +545,15 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
if (AppIsOffScreenRenderingEnabled()) {
|
||||
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
|
||||
bool transparent =
|
||||
const bool transparent =
|
||||
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
cmd_line->HasSwitch(cefclient::kShowUpdateRect);
|
||||
|
||||
// Create the GTKGL surface.
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent, vbox);
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent,
|
||||
show_update_rect, vbox);
|
||||
|
||||
// Show the GTK window.
|
||||
gtk_widget_show_all(GTK_WIDGET(window));
|
||||
|
|
|
@ -488,11 +488,14 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
|
|||
|
||||
if (AppIsOffScreenRenderingEnabled()) {
|
||||
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
|
||||
bool transparent =
|
||||
const bool transparent =
|
||||
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
cmd_line->HasSwitch(cefclient::kShowUpdateRect);
|
||||
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent, contentView,
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent,
|
||||
show_update_rect, contentView,
|
||||
CefRect(0, 0, kWindowWidth, kWindowHeight));
|
||||
window_info.SetAsWindowless(osr_window->GetWindowHandle(), transparent);
|
||||
g_handler->SetOSRHandler(osr_window->GetRenderHandler().get());
|
||||
|
|
|
@ -1096,12 +1096,14 @@ class ScopedGLContext {
|
|||
// static
|
||||
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView) {
|
||||
DCHECK(browser_provider);
|
||||
if (!browser_provider)
|
||||
return NULL;
|
||||
|
||||
return new OSRWindow(browser_provider, transparent, parentView);
|
||||
return new OSRWindow(browser_provider, transparent, show_update_rect,
|
||||
parentView);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -1241,8 +1243,9 @@ void OSRWindow::ApplyPopupOffset(int& x, int& y) const {
|
|||
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView)
|
||||
: renderer_(transparent),
|
||||
: renderer_(transparent, show_update_rect),
|
||||
browser_provider_(browser_provider),
|
||||
gl_enabled_(false),
|
||||
painting_popup_(false),
|
||||
|
|
|
@ -24,6 +24,7 @@ class OSRWindow : public ClientHandler::RenderHandler {
|
|||
// object.
|
||||
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView);
|
||||
|
||||
static CefRefPtr<OSRWindow> From(
|
||||
|
@ -73,6 +74,7 @@ class OSRWindow : public ClientHandler::RenderHandler {
|
|||
private:
|
||||
OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
ClientWindowHandle parentView);
|
||||
virtual ~OSRWindow();
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ class OSRBrowserProvider {
|
|||
id endWheelMonitor_;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency;
|
||||
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency
|
||||
andShowUpdateRect:(bool)show_update_rect;
|
||||
- (NSPoint)getClickPointForEvent:(NSEvent*)event;
|
||||
- (void)getKeyEvent:(CefKeyEvent&)keyEvent forEvent:(NSEvent*)event;
|
||||
- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event;
|
||||
|
@ -122,6 +123,7 @@ class OSRWindow {
|
|||
public:
|
||||
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
CefWindowHandle parentView,
|
||||
const CefRect& frame);
|
||||
|
||||
|
@ -134,6 +136,7 @@ class OSRWindow {
|
|||
private:
|
||||
OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
CefWindowHandle parentView,
|
||||
const CefRect& frame);
|
||||
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
#include "cefclient/osrenderer.h"
|
||||
#include "cefclient/resource_util.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// This method will return YES for OS X versions 10.7.3 and later, and NO
|
||||
// otherwise.
|
||||
// Used to prevent a crash when building with the 10.7 SDK and accessing the
|
||||
// notification below. See: http://crbug.com/260595.
|
||||
static BOOL SupportsBackingPropertiesChangedNotification() {
|
||||
BOOL SupportsBackingPropertiesChangedNotification() {
|
||||
// windowDidChangeBackingProperties: method has been added to the
|
||||
// NSWindowDelegate protocol in 10.7.3, at the same time as the
|
||||
// NSWindowDidChangeBackingPropertiesNotification notification was added.
|
||||
|
@ -43,6 +45,25 @@ static BOOL SupportsBackingPropertiesChangedNotification() {
|
|||
return methodDescription.name != NULL || methodDescription.types != NULL;
|
||||
}
|
||||
|
||||
class ScopedGLContext {
|
||||
public:
|
||||
ScopedGLContext(ClientOpenGLView* view, bool swap_buffers)
|
||||
: swap_buffers_(swap_buffers) {
|
||||
context_ = [view openGLContext];
|
||||
[context_ makeCurrentContext];
|
||||
}
|
||||
~ScopedGLContext() {
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
if (swap_buffers_)
|
||||
[context_ flushBuffer];
|
||||
}
|
||||
private:
|
||||
NSOpenGLContext* context_;
|
||||
const bool swap_buffers_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@interface ClientOpenGLView ()
|
||||
- (void)resetDragDrop;
|
||||
- (void)fillPasteboard;
|
||||
|
@ -232,8 +253,7 @@ void ClientOSRHandler::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
return;
|
||||
}
|
||||
|
||||
NSOpenGLContext* context = [view_ openGLContext];
|
||||
[context makeCurrentContext];
|
||||
ScopedGLContext scoped_gl_context(view_, true);
|
||||
|
||||
view_->renderer_->OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
|
||||
|
@ -248,7 +268,6 @@ void ClientOSRHandler::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
}
|
||||
|
||||
view_->renderer_->Render();
|
||||
[context flushBuffer];
|
||||
}
|
||||
|
||||
void ClientOSRHandler::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
|
@ -286,7 +305,8 @@ void ClientOSRHandler::SetLoading(bool isLoading) {
|
|||
|
||||
@synthesize was_last_mouse_down_on_view = was_last_mouse_down_on_view_;
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency {
|
||||
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency
|
||||
andShowUpdateRect:(bool)show_update_rect {
|
||||
NSOpenGLPixelFormat * pixelFormat =
|
||||
[[NSOpenGLPixelFormat alloc]
|
||||
initWithAttributes:(NSOpenGLPixelFormatAttribute[]) {
|
||||
|
@ -299,7 +319,7 @@ void ClientOSRHandler::SetLoading(bool isLoading) {
|
|||
|
||||
self = [super initWithFrame:frame pixelFormat:pixelFormat];
|
||||
if (self) {
|
||||
renderer_ = new ClientOSRenderer(transparency);
|
||||
renderer_ = new ClientOSRenderer(transparency, show_update_rect);
|
||||
rotating_ = false;
|
||||
endWheelMonitor_ = nil;
|
||||
|
||||
|
@ -1191,18 +1211,23 @@ void ClientOSRHandler::SetLoading(bool isLoading) {
|
|||
|
||||
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
CefWindowHandle parentView,
|
||||
const CefRect& frame) {
|
||||
return new OSRWindow(browser_provider, transparent, parentView, frame);
|
||||
return new OSRWindow(browser_provider, transparent, show_update_rect,
|
||||
parentView, frame);
|
||||
}
|
||||
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect,
|
||||
CefWindowHandle parentView,
|
||||
const CefRect& frame) {
|
||||
NSRect window_rect = NSMakeRect(frame.x, frame.y, frame.width, frame.height);
|
||||
ClientOpenGLView* view = [[ClientOpenGLView alloc] initWithFrame:window_rect
|
||||
andTransparency:transparent];
|
||||
ClientOpenGLView* view =
|
||||
[[ClientOpenGLView alloc] initWithFrame:window_rect
|
||||
andTransparency:transparent
|
||||
andShowUpdateRect:show_update_rect];
|
||||
this->view_ = view;
|
||||
[parentView addSubview:view];
|
||||
[view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
||||
|
|
|
@ -10,14 +10,42 @@
|
|||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "cefclient/resource.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class ScopedGLContext {
|
||||
public:
|
||||
ScopedGLContext(HDC hdc, HGLRC hglrc, bool swap_buffers)
|
||||
: hdc_(hdc),
|
||||
swap_buffers_(swap_buffers) {
|
||||
BOOL result = wglMakeCurrent(hdc, hglrc);
|
||||
DCHECK(result);
|
||||
}
|
||||
~ScopedGLContext() {
|
||||
BOOL result = wglMakeCurrent(NULL, NULL);
|
||||
DCHECK(result);
|
||||
if (swap_buffers_) {
|
||||
result = SwapBuffers(hdc_);
|
||||
DCHECK(result);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const HDC hdc_;
|
||||
const bool swap_buffers_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
CefRefPtr<OSRWindow> OSRWindow::Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent) {
|
||||
CefRefPtr<OSRWindow> OSRWindow::Create(
|
||||
OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect) {
|
||||
DCHECK(browser_provider);
|
||||
if (!browser_provider)
|
||||
return NULL;
|
||||
|
||||
return new OSRWindow(browser_provider, transparent);
|
||||
return new OSRWindow(browser_provider, transparent, show_update_rect);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -135,7 +163,8 @@ void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
if (!hDC_)
|
||||
EnableGL();
|
||||
|
||||
wglMakeCurrent(hDC_, hRC_);
|
||||
{
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, true);
|
||||
renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height);
|
||||
if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) {
|
||||
painting_popup_ = true;
|
||||
|
@ -143,7 +172,7 @@ void OSRWindow::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
painting_popup_ = false;
|
||||
}
|
||||
renderer_.Render();
|
||||
SwapBuffers(hDC_);
|
||||
}
|
||||
}
|
||||
|
||||
void OSRWindow::OnCursorChange(CefRefPtr<CefBrowser> browser,
|
||||
|
@ -249,8 +278,10 @@ CefBrowserHost::DragOperationsMask
|
|||
|
||||
#endif // defined(CEF_USE_ATL)
|
||||
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, bool transparent)
|
||||
: renderer_(transparent),
|
||||
OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect)
|
||||
: renderer_(transparent, show_update_rect),
|
||||
browser_provider_(browser_provider),
|
||||
hWnd_(NULL),
|
||||
hDC_(NULL),
|
||||
|
@ -275,9 +306,8 @@ void OSRWindow::Render() {
|
|||
if (!hDC_)
|
||||
EnableGL();
|
||||
|
||||
wglMakeCurrent(hDC_, hRC_);
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, true);
|
||||
renderer_.Render();
|
||||
SwapBuffers(hDC_);
|
||||
}
|
||||
|
||||
void OSRWindow::EnableGL() {
|
||||
|
@ -303,8 +333,8 @@ void OSRWindow::EnableGL() {
|
|||
|
||||
// Create and enable the render context.
|
||||
hRC_ = wglCreateContext(hDC_);
|
||||
wglMakeCurrent(hDC_, hRC_);
|
||||
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, false);
|
||||
renderer_.Initialize();
|
||||
}
|
||||
|
||||
|
@ -314,11 +344,15 @@ void OSRWindow::DisableGL() {
|
|||
if (!hDC_)
|
||||
return;
|
||||
|
||||
{
|
||||
ScopedGLContext scoped_gl_context(hDC_, hRC_, false);
|
||||
renderer_.Cleanup();
|
||||
}
|
||||
|
||||
if (IsWindow(hWnd_)) {
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(hRC_);
|
||||
// wglDeleteContext will make the context not current before deleting it.
|
||||
BOOL result = wglDeleteContext(hRC_);
|
||||
DCHECK(result);
|
||||
ReleaseDC(hWnd_, hDC_);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ class OSRWindow : public ClientHandler::RenderHandler
|
|||
// Create a new OSRWindow instance. |browser_provider| must outlive this
|
||||
// object.
|
||||
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
|
||||
bool transparent);
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
|
||||
static CefRefPtr<OSRWindow> From(
|
||||
CefRefPtr<ClientHandler::RenderHandler> renderHandler);
|
||||
|
@ -100,7 +101,9 @@ class OSRWindow : public ClientHandler::RenderHandler
|
|||
static int GetCefMouseModifiers(WPARAM wparam);
|
||||
|
||||
private:
|
||||
OSRWindow(OSRBrowserProvider* browser_provider, bool transparent);
|
||||
OSRWindow(OSRBrowserProvider* browser_provider,
|
||||
bool transparent,
|
||||
bool show_update_rect);
|
||||
virtual ~OSRWindow();
|
||||
|
||||
void Render();
|
||||
|
|
|
@ -463,11 +463,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
|
||||
if (AppIsOffScreenRenderingEnabled()) {
|
||||
CefRefPtr<CefCommandLine> cmd_line = AppGetCommandLine();
|
||||
bool transparent =
|
||||
const bool transparent =
|
||||
cmd_line->HasSwitch(cefclient::kTransparentPaintingEnabled);
|
||||
const bool show_update_rect =
|
||||
cmd_line->HasSwitch(cefclient::kShowUpdateRect);
|
||||
|
||||
CefRefPtr<OSRWindow> osr_window =
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent);
|
||||
OSRWindow::Create(&g_main_browser_provider, transparent,
|
||||
show_update_rect);
|
||||
osr_window->CreateWidget(hWnd, rect, hInst, szOSRWindowClass);
|
||||
info.SetAsWindowless(osr_window->hwnd(), transparent);
|
||||
g_handler->SetOSRHandler(osr_window.get());
|
||||
|
|
|
@ -24,6 +24,7 @@ const char kUrl[] = "url";
|
|||
const char kOffScreenRenderingEnabled[] = "off-screen-rendering-enabled";
|
||||
const char kOffScreenFrameRate[] = "off-screen-frame-rate";
|
||||
const char kTransparentPaintingEnabled[] = "transparent-painting-enabled";
|
||||
const char kShowUpdateRect[] = "show-update-rect";
|
||||
const char kMouseCursorChangeDisabled[] = "mouse-cursor-change-disabled";
|
||||
|
||||
} // namespace cefclient
|
||||
|
|
|
@ -16,6 +16,7 @@ extern const char kUrl[];
|
|||
extern const char kOffScreenRenderingEnabled[];
|
||||
extern const char kOffScreenFrameRate[];
|
||||
extern const char kTransparentPaintingEnabled[];
|
||||
extern const char kShowUpdateRect[];
|
||||
extern const char kMouseCursorChangeDisabled[];
|
||||
|
||||
} // namespace cefclient
|
||||
|
|
|
@ -28,9 +28,21 @@
|
|||
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
|
||||
#endif
|
||||
|
||||
// DCHECK on gl errors.
|
||||
#ifndef NDEBUG
|
||||
#define VERIFY_NO_ERROR { \
|
||||
int _gl_error = glGetError(); \
|
||||
DCHECK(_gl_error == GL_NO_ERROR) << \
|
||||
"glGetError returned " << _gl_error; \
|
||||
}
|
||||
#else
|
||||
#define VERIFY_NO_ERROR
|
||||
#endif
|
||||
|
||||
ClientOSRenderer::ClientOSRenderer(bool transparent)
|
||||
ClientOSRenderer::ClientOSRenderer(bool transparent,
|
||||
bool show_update_rect)
|
||||
: transparent_(transparent),
|
||||
show_update_rect_(show_update_rect),
|
||||
initialized_(false),
|
||||
texture_id_(0),
|
||||
view_width_(0),
|
||||
|
@ -47,21 +59,23 @@ void ClientOSRenderer::Initialize() {
|
|||
if (initialized_)
|
||||
return;
|
||||
|
||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); VERIFY_NO_ERROR;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); VERIFY_NO_ERROR;
|
||||
|
||||
// Necessary for non-power-of-2 textures to render correctly.
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); VERIFY_NO_ERROR;
|
||||
|
||||
// Create the texture.
|
||||
glGenTextures(1, &texture_id_);
|
||||
DCHECK_NE(texture_id_, 0U);
|
||||
glGenTextures(1, &texture_id_); VERIFY_NO_ERROR;
|
||||
DCHECK_NE(texture_id_, 0U); VERIFY_NO_ERROR;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_); VERIFY_NO_ERROR;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_NEAREST); VERIFY_NO_ERROR;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
GL_NEAREST); VERIFY_NO_ERROR;
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); VERIFY_NO_ERROR;
|
||||
|
||||
initialized_ = true;
|
||||
}
|
||||
|
@ -87,19 +101,19 @@ void ClientOSRenderer::Render() {
|
|||
{0.0f, 0.0f, -1.0f, 1.0f, 0.0f}
|
||||
};
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); VERIFY_NO_ERROR;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW); VERIFY_NO_ERROR;
|
||||
glLoadIdentity(); VERIFY_NO_ERROR;
|
||||
|
||||
// Match GL units to screen coordinates.
|
||||
glViewport(0, 0, view_width_, view_height_);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, 0, view_width_, view_height_, 0.1, 100.0);
|
||||
glViewport(0, 0, view_width_, view_height_); VERIFY_NO_ERROR;
|
||||
glMatrixMode(GL_PROJECTION); VERIFY_NO_ERROR;
|
||||
glLoadIdentity(); VERIFY_NO_ERROR;
|
||||
|
||||
// Draw the background gradient.
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS); VERIFY_NO_ERROR;
|
||||
// Don't check for errors until glEnd().
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.0, 0.0, 0.0, 1.0); // red
|
||||
glVertex2f(-1.0, -1.0);
|
||||
|
@ -107,38 +121,78 @@ void ClientOSRenderer::Render() {
|
|||
glColor4f(0.0, 0.0, 1.0, 1.0); // blue
|
||||
glVertex2f(1.0, 1.0);
|
||||
glVertex2f(-1.0, 1.0);
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
glEnd(); VERIFY_NO_ERROR;
|
||||
glPopAttrib(); VERIFY_NO_ERROR;
|
||||
|
||||
// Rotate the view based on the mouse spin.
|
||||
if (spin_x_ != 0)
|
||||
glRotatef(-spin_x_, 1.0f, 0.0f, 0.0f);
|
||||
if (spin_y_ != 0)
|
||||
glRotatef(-spin_y_, 0.0f, 1.0f, 0.0f);
|
||||
if (spin_x_ != 0) {
|
||||
glRotatef(-spin_x_, 1.0f, 0.0f, 0.0f); VERIFY_NO_ERROR;
|
||||
}
|
||||
if (spin_y_ != 0) {
|
||||
glRotatef(-spin_y_, 0.0f, 1.0f, 0.0f); VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
if (transparent_) {
|
||||
// Alpha blending style. Texture values have premultiplied alpha.
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); VERIFY_NO_ERROR;
|
||||
|
||||
// Enable alpha blending.
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_BLEND); VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
// Enable 2D textures.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_2D); VERIFY_NO_ERROR;
|
||||
|
||||
// Draw the facets with the texture.
|
||||
DCHECK_NE(texture_id_, 0U);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
glInterleavedArrays(GL_T2F_V3F, 0, vertices);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
DCHECK_NE(texture_id_, 0U); VERIFY_NO_ERROR;
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_); VERIFY_NO_ERROR;
|
||||
glInterleavedArrays(GL_T2F_V3F, 0, vertices); VERIFY_NO_ERROR;
|
||||
glDrawArrays(GL_QUADS, 0, 4); VERIFY_NO_ERROR;
|
||||
|
||||
// Disable 2D textures.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_TEXTURE_2D); VERIFY_NO_ERROR;
|
||||
|
||||
if (transparent_) {
|
||||
// Disable alpha blending.
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_BLEND); VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
// Draw a rectangle around the update region.
|
||||
if (show_update_rect_ && !update_rect_.IsEmpty()) {
|
||||
int left = update_rect_.x;
|
||||
int right = update_rect_.x + update_rect_.width;
|
||||
int top = update_rect_.y;
|
||||
int bottom = update_rect_.y + update_rect_.height;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Shrink the box so that top & right sides are drawn.
|
||||
top += 1;
|
||||
right -= 1;
|
||||
#else
|
||||
// Shrink the box so that left & bottom sides are drawn.
|
||||
left += 1;
|
||||
bottom -= 1;
|
||||
#endif
|
||||
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS); VERIFY_NO_ERROR
|
||||
glMatrixMode(GL_PROJECTION); VERIFY_NO_ERROR;
|
||||
glPushMatrix(); VERIFY_NO_ERROR;
|
||||
glLoadIdentity(); VERIFY_NO_ERROR;
|
||||
glOrtho(0, view_width_, view_height_, 0, 0, 1); VERIFY_NO_ERROR;
|
||||
|
||||
glLineWidth(1); VERIFY_NO_ERROR;
|
||||
glColor3f(1.0f, 0.0f, 0.0f); VERIFY_NO_ERROR;
|
||||
// Don't check for errors until glEnd().
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(left, top);
|
||||
glVertex2i(right, top);
|
||||
glVertex2i(right, bottom);
|
||||
glVertex2i(left, bottom);
|
||||
glVertex2i(left, top);
|
||||
glEnd(); VERIFY_NO_ERROR;
|
||||
|
||||
glPopMatrix(); VERIFY_NO_ERROR;
|
||||
glPopAttrib(); VERIFY_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,14 +246,14 @@ void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
|
||||
if (transparent_) {
|
||||
// Enable alpha blending.
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_BLEND); VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
// Enable 2D textures.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_2D); VERIFY_NO_ERROR;
|
||||
|
||||
DCHECK_NE(texture_id_, 0U);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_); VERIFY_NO_ERROR;
|
||||
|
||||
if (type == PET_VIEW) {
|
||||
int old_width = view_width_;
|
||||
|
@ -208,24 +262,30 @@ void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
view_width_ = width;
|
||||
view_height_ = height;
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, view_width_);
|
||||
if (show_update_rect_)
|
||||
update_rect_ = dirtyRects[0];
|
||||
|
||||
if (old_width != view_width_ || old_height != view_height_) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, view_width_); VERIFY_NO_ERROR;
|
||||
|
||||
if (old_width != view_width_ || old_height != view_height_ ||
|
||||
(dirtyRects.size() == 1 &&
|
||||
dirtyRects[0] == CefRect(0, 0, view_width_, view_height_))) {
|
||||
// Update/resize the whole texture.
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width_, view_height_, 0,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); VERIFY_NO_ERROR;
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); VERIFY_NO_ERROR;
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_RGBA, view_width_, view_height_, 0,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer); VERIFY_NO_ERROR;
|
||||
} else {
|
||||
// Update just the dirty rectangles.
|
||||
CefRenderHandler::RectList::const_iterator i = dirtyRects.begin();
|
||||
for (; i != dirtyRects.end(); ++i) {
|
||||
const CefRect& rect = *i;
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x); VERIFY_NO_ERROR;
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y); VERIFY_NO_ERROR;
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width,
|
||||
rect.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
buffer);
|
||||
buffer); VERIFY_NO_ERROR;
|
||||
}
|
||||
}
|
||||
} else if (type == PET_POPUP && popup_rect_.width > 0 &&
|
||||
|
@ -250,19 +310,19 @@ void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
|
|||
h -= y + h - view_height_;
|
||||
|
||||
// Update the popup rectangle.
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width); VERIFY_NO_ERROR;
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels); VERIFY_NO_ERROR;
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows); VERIFY_NO_ERROR;
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA,
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV, buffer); VERIFY_NO_ERROR;
|
||||
}
|
||||
|
||||
// Disable 2D textures.
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_TEXTURE_2D); VERIFY_NO_ERROR;
|
||||
|
||||
if (transparent_) {
|
||||
// Disable alpha blending.
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_BLEND); VERIFY_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
class ClientOSRenderer {
|
||||
public:
|
||||
// The context must outlive this object.
|
||||
explicit ClientOSRenderer(bool transparent);
|
||||
ClientOSRenderer(bool transparent,
|
||||
bool show_update_rect);
|
||||
virtual ~ClientOSRenderer();
|
||||
|
||||
// Initialize the OpenGL environment.
|
||||
|
@ -50,7 +50,8 @@ class ClientOSRenderer {
|
|||
void ClearPopupRects();
|
||||
|
||||
private:
|
||||
bool transparent_;
|
||||
const bool transparent_;
|
||||
const bool show_update_rect_;
|
||||
bool initialized_;
|
||||
unsigned int texture_id_;
|
||||
int view_width_;
|
||||
|
@ -59,6 +60,7 @@ class ClientOSRenderer {
|
|||
CefRect original_popup_rect_;
|
||||
float spin_x_;
|
||||
float spin_y_;
|
||||
CefRect update_rect_;
|
||||
};
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_OSRENDERER_H_
|
||||
|
|
Loading…
Reference in New Issue