| Index: cc/output/gl_renderer.cc
|
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
|
| index 87195747d0bcbeafddd72bfbe42d3db936fc5dd4..29df50f1746631591b34b3daeefd055d6ae5d7b4 100644
|
| --- a/cc/output/gl_renderer.cc
|
| +++ b/cc/output/gl_renderer.cc
|
| @@ -177,6 +177,40 @@ const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
|
|
|
| } // anonymous namespace
|
|
|
| +class GLRenderer::ScopedUseGrContext {
|
| + public:
|
| + static scoped_ptr<ScopedUseGrContext> Create(GLRenderer* renderer,
|
| + DrawingFrame* frame) {
|
| + if (!renderer->output_surface_->context_provider()->GrContext())
|
| + return scoped_ptr<ScopedUseGrContext>();
|
| + return make_scoped_ptr(new ScopedUseGrContext(renderer, frame));
|
| + }
|
| +
|
| + ~ScopedUseGrContext() { PassControlToGLRenderer(); }
|
| +
|
| + GrContext* context() const {
|
| + return renderer_->output_surface_->context_provider()->GrContext();
|
| + }
|
| +
|
| + private:
|
| + ScopedUseGrContext(GLRenderer* renderer, DrawingFrame* frame)
|
| + : renderer_(renderer), frame_(frame) {
|
| + PassControlToSkia();
|
| + }
|
| +
|
| + void PassControlToSkia() { context()->resetContext(); }
|
| +
|
| + void PassControlToGLRenderer() {
|
| + renderer_->RestoreGLState();
|
| + renderer_->RestoreFramebuffer(frame_);
|
| + }
|
| +
|
| + GLRenderer* renderer_;
|
| + DrawingFrame* frame_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ScopedUseGrContext);
|
| +};
|
| +
|
| struct GLRenderer::PendingAsyncReadPixels {
|
| PendingAsyncReadPixels() : buffer(0) {}
|
|
|
| @@ -300,7 +334,7 @@ GLRenderer::GLRenderer(RendererClient* client,
|
| // so we only need to avoid POT textures if we have an NPOT fast-path.
|
| capabilities_.avoid_pow2_textures = context_caps.gpu.fast_npot_mo8_textures;
|
|
|
| - capabilities_.using_offscreen_context3d = true;
|
| + capabilities_.using_offscreen_context3d = false;
|
|
|
| capabilities_.using_map_image =
|
| settings_->use_map_image && context_caps.gpu.map_image;
|
| @@ -569,25 +603,21 @@ void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
|
| GLC(gl_, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0));
|
| }
|
|
|
| -static SkBitmap ApplyImageFilter(GLRenderer* renderer,
|
| - ContextProvider* offscreen_contexts,
|
| - const gfx::Point& origin,
|
| - SkImageFilter* filter,
|
| - ScopedResource* source_texture_resource) {
|
| +static SkBitmap ApplyImageFilter(
|
| + scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
|
| + ResourceProvider* resource_provider,
|
| + const gfx::Point& origin,
|
| + SkImageFilter* filter,
|
| + ScopedResource* source_texture_resource) {
|
| if (!filter)
|
| return SkBitmap();
|
|
|
| - if (!offscreen_contexts || !offscreen_contexts->GrContext())
|
| + if (!use_gr_context)
|
| return SkBitmap();
|
|
|
| - ResourceProvider::ScopedReadLockGL lock(renderer->resource_provider(),
|
| + ResourceProvider::ScopedReadLockGL lock(resource_provider,
|
| source_texture_resource->id());
|
|
|
| - // Flush the compositor context to ensure that textures there are available
|
| - // in the shared context. Do this after locking/creating the compositor
|
| - // texture.
|
| - renderer->resource_provider()->Flush();
|
| -
|
| // Wrap the source texture in a Ganesh platform texture.
|
| GrBackendTextureDesc backend_texture_description;
|
| backend_texture_description.fWidth = source_texture_resource->size().width();
|
| @@ -597,7 +627,7 @@ static SkBitmap ApplyImageFilter(GLRenderer* renderer,
|
| backend_texture_description.fTextureHandle = lock.texture_id();
|
| backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
| skia::RefPtr<GrTexture> texture =
|
| - skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture(
|
| + skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
|
| backend_texture_description));
|
|
|
| SkImageInfo info = {
|
| @@ -622,12 +652,12 @@ static SkBitmap ApplyImageFilter(GLRenderer* renderer,
|
| desc.fConfig = kSkia8888_GrPixelConfig;
|
| desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
| GrAutoScratchTexture scratch_texture(
|
| - offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch);
|
| + use_gr_context->context(), desc, GrContext::kExact_ScratchTexMatch);
|
| skia::RefPtr<GrTexture> backing_store =
|
| skia::AdoptRef(scratch_texture.detach());
|
|
|
| // Create a device and canvas using that backing store.
|
| - SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get());
|
| + SkGpuDevice device(use_gr_context->context(), backing_store.get());
|
| SkCanvas canvas(&device);
|
|
|
| // Draw the source bitmap through the filter to the canvas.
|
| @@ -641,25 +671,22 @@ static SkBitmap ApplyImageFilter(GLRenderer* renderer,
|
| canvas.translate(SkIntToScalar(-origin.x()), SkIntToScalar(-origin.y()));
|
| canvas.drawSprite(source, 0, 0, &paint);
|
|
|
| - // Flush skia context so that all the rendered stuff appears on the
|
| - // texture.
|
| - offscreen_contexts->GrContext()->flush();
|
| -
|
| - // Flush the GL context so rendering results from this context are
|
| - // visible in the compositor's context.
|
| - offscreen_contexts->ContextGL()->Flush();
|
| + // Flush the GrContext to ensure all buffered GL calls are drawn to the
|
| + // backing store before we access and return it, and have cc begin using the
|
| + // GL context again.
|
| + use_gr_context->context()->flush();
|
|
|
| return device.accessBitmap(false);
|
| }
|
|
|
| static SkBitmap ApplyBlendModeWithBackdrop(
|
| - GLRenderer* renderer,
|
| - ContextProvider* offscreen_contexts,
|
| + scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
|
| + ResourceProvider* resource_provider,
|
| SkBitmap source_bitmap_with_filters,
|
| ScopedResource* source_texture_resource,
|
| ScopedResource* background_texture_resource,
|
| SkXfermode::Mode blend_mode) {
|
| - if (!offscreen_contexts || !offscreen_contexts->GrContext())
|
| + if (!use_gr_context)
|
| return source_bitmap_with_filters;
|
|
|
| DCHECK(background_texture_resource);
|
| @@ -681,17 +708,12 @@ static SkBitmap ApplyBlendModeWithBackdrop(
|
| source_texture_with_filters_id = texture->getTextureHandle();
|
| } else {
|
| lock.reset(new ResourceProvider::ScopedReadLockGL(
|
| - renderer->resource_provider(), source_texture_resource->id()));
|
| + resource_provider, source_texture_resource->id()));
|
| source_texture_with_filters_id = lock->texture_id();
|
| }
|
|
|
| ResourceProvider::ScopedReadLockGL lock_background(
|
| - renderer->resource_provider(), background_texture_resource->id());
|
| -
|
| - // Flush the compositor context to ensure that textures there are available
|
| - // in the shared context. Do this after locking/creating the compositor
|
| - // texture.
|
| - renderer->resource_provider()->Flush();
|
| + resource_provider, background_texture_resource->id());
|
|
|
| // Wrap the source texture in a Ganesh platform texture.
|
| GrBackendTextureDesc backend_texture_description;
|
| @@ -702,14 +724,14 @@ static SkBitmap ApplyBlendModeWithBackdrop(
|
| backend_texture_description.fHeight = source_size.height();
|
| backend_texture_description.fTextureHandle = source_texture_with_filters_id;
|
| skia::RefPtr<GrTexture> source_texture =
|
| - skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture(
|
| + skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
|
| backend_texture_description));
|
|
|
| backend_texture_description.fWidth = background_size.width();
|
| backend_texture_description.fHeight = background_size.height();
|
| backend_texture_description.fTextureHandle = lock_background.texture_id();
|
| skia::RefPtr<GrTexture> background_texture =
|
| - skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture(
|
| + skia::AdoptRef(use_gr_context->context()->wrapBackendTexture(
|
| backend_texture_description));
|
|
|
| SkImageInfo source_info = {
|
| @@ -748,12 +770,12 @@ static SkBitmap ApplyBlendModeWithBackdrop(
|
| desc.fConfig = kSkia8888_GrPixelConfig;
|
| desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
| GrAutoScratchTexture scratch_texture(
|
| - offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch);
|
| + use_gr_context->context(), desc, GrContext::kExact_ScratchTexMatch);
|
| skia::RefPtr<GrTexture> backing_store =
|
| skia::AdoptRef(scratch_texture.detach());
|
|
|
| // Create a device and canvas using that backing store.
|
| - SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get());
|
| + SkGpuDevice device(use_gr_context->context(), backing_store.get());
|
| SkCanvas canvas(&device);
|
|
|
| // Draw the source bitmap through the filter to the canvas.
|
| @@ -763,13 +785,10 @@ static SkBitmap ApplyBlendModeWithBackdrop(
|
| paint.setXfermodeMode(blend_mode);
|
| canvas.drawSprite(source, 0, 0, &paint);
|
|
|
| - // Flush skia context so that all the rendered stuff appears on the
|
| - // texture.
|
| - offscreen_contexts->GrContext()->flush();
|
| -
|
| - // Flush the GL context so rendering results from this context are
|
| - // visible in the compositor's context.
|
| - offscreen_contexts->ContextGL()->Flush();
|
| + // Flush the GrContext to ensure all buffered GL calls are drawn to the
|
| + // backing store before we access and return it, and have cc begin using the
|
| + // GL context again.
|
| + use_gr_context->context()->flush();
|
|
|
| return device.accessBitmap(false);
|
| }
|
| @@ -847,8 +866,8 @@ scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters(
|
| SkBitmap filtered_device_background;
|
| if (apply_background_filters) {
|
| filtered_device_background =
|
| - ApplyImageFilter(this,
|
| - frame->offscreen_context_provider,
|
| + ApplyImageFilter(ScopedUseGrContext::Create(this, frame),
|
| + resource_provider_,
|
| quad->rect.origin(),
|
| filter.get(),
|
| device_background_texture.get());
|
| @@ -959,8 +978,6 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| SkBitmap filter_bitmap;
|
| SkScalar color_matrix[20];
|
| bool use_color_matrix = false;
|
| - // TODO(ajuma): Always use RenderSurfaceFilters::BuildImageFilter, not just
|
| - // when we have a reference filter.
|
| if (!quad->filters.IsEmpty()) {
|
| skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
|
| quad->filters, contents_texture->size());
|
| @@ -978,11 +995,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| // in the compositor.
|
| use_color_matrix = true;
|
| } else {
|
| - filter_bitmap = ApplyImageFilter(this,
|
| - frame->offscreen_context_provider,
|
| - quad->rect.origin(),
|
| - filter.get(),
|
| - contents_texture);
|
| + filter_bitmap =
|
| + ApplyImageFilter(ScopedUseGrContext::Create(this, frame),
|
| + resource_provider_,
|
| + quad->rect.origin(),
|
| + filter.get(),
|
| + contents_texture);
|
| }
|
| }
|
| }
|
| @@ -990,8 +1008,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
|
| if (quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode &&
|
| background_texture) {
|
| filter_bitmap =
|
| - ApplyBlendModeWithBackdrop(this,
|
| - frame->offscreen_context_provider,
|
| + ApplyBlendModeWithBackdrop(ScopedUseGrContext::Create(this, frame),
|
| + resource_provider_,
|
| filter_bitmap,
|
| contents_texture,
|
| background_texture.get(),
|
| @@ -3111,24 +3129,53 @@ void GLRenderer::CleanupSharedObjects() {
|
| }
|
|
|
| void GLRenderer::ReinitializeGLState() {
|
| - // Bind the common vertex attributes used for drawing all the layers.
|
| + is_scissor_enabled_ = false;
|
| + scissor_rect_needs_reset_ = true;
|
| + stencil_shadow_ = false;
|
| + blend_shadow_ = true;
|
| + program_shadow_ = 0;
|
| +
|
| + RestoreGLState();
|
| +}
|
| +
|
| +void GLRenderer::RestoreGLState() {
|
| + // This restores the current GLRenderer state to the GL context.
|
| +
|
| shared_geometry_->PrepareForDraw();
|
|
|
| GLC(gl_, gl_->Disable(GL_DEPTH_TEST));
|
| GLC(gl_, gl_->Disable(GL_CULL_FACE));
|
| GLC(gl_, gl_->ColorMask(true, true, true, true));
|
| - GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
|
| - stencil_shadow_ = false;
|
| - GLC(gl_, gl_->Enable(GL_BLEND));
|
| - blend_shadow_ = true;
|
| GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
| GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
|
| - program_shadow_ = 0;
|
|
|
| - // Make sure scissoring starts as disabled.
|
| - is_scissor_enabled_ = false;
|
| - GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
|
| - scissor_rect_needs_reset_ = true;
|
| + if (program_shadow_)
|
| + gl_->UseProgram(program_shadow_);
|
| +
|
| + if (stencil_shadow_)
|
| + GLC(gl_, gl_->Enable(GL_STENCIL_TEST));
|
| + else
|
| + GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
|
| +
|
| + if (blend_shadow_)
|
| + GLC(gl_, gl_->Enable(GL_BLEND));
|
| + else
|
| + GLC(gl_, gl_->Disable(GL_BLEND));
|
| +
|
| + if (is_scissor_enabled_) {
|
| + GLC(gl_, gl_->Enable(GL_SCISSOR_TEST));
|
| + GLC(gl_,
|
| + gl_->Scissor(scissor_rect_.x(),
|
| + scissor_rect_.y(),
|
| + scissor_rect_.width(),
|
| + scissor_rect_.height()));
|
| + } else {
|
| + GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
|
| + }
|
| +}
|
| +
|
| +void GLRenderer::RestoreFramebuffer(DrawingFrame* frame) {
|
| + UseRenderPass(frame, frame->current_render_pass);
|
| }
|
|
|
| bool GLRenderer::IsContextLost() {
|
| @@ -3150,7 +3197,7 @@ void GLRenderer::ScheduleOverlays(DrawingFrame* frame) {
|
|
|
| pending_overlay_resources_.push_back(
|
| make_scoped_ptr(new ResourceProvider::ScopedReadLockGL(
|
| - resource_provider(), overlay.resource_id)));
|
| + resource_provider_, overlay.resource_id)));
|
|
|
| context_support_->ScheduleOverlayPlane(
|
| overlay.plane_z_order,
|
|
|