Chromium Code Reviews| Index: cc/output/gl_renderer.cc |
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
| index 87195747d0bcbeafddd72bfbe42d3db936fc5dd4..2222a104905a569ae48bac5a3bae885cf58f43c9 100644 |
| --- a/cc/output/gl_renderer.cc |
| +++ b/cc/output/gl_renderer.cc |
| @@ -177,6 +177,39 @@ const float kAntiAliasingEpsilon = 1.0f / 1024.0f; |
| } // anonymous namespace |
| +class GLRenderer::UseGrContext { |
|
enne (OOO)
2014/04/23 19:53:41
ScopedUseGrContext?
Stephen White
2014/04/23 19:57:20
I find this guard class to be too much magic. I li
danakj
2014/04/23 20:11:10
2014/04/23 19:57:20, Stephen White wrote:
|
| + public: |
| + static scoped_ptr<UseGrContext> Create(GLRenderer* renderer, |
| + DrawingFrame* frame) { |
| + if (!renderer->output_surface_->context_provider()->GrContext()) |
| + return scoped_ptr<UseGrContext>(); |
| + return make_scoped_ptr(new UseGrContext(renderer, frame)); |
| + } |
| + |
| + ~UseGrContext() { PassControlToGLRenderer(); } |
| + |
| + GrContext* context() const { |
| + return renderer_->output_surface_->context_provider()->GrContext(); |
| + } |
| + |
| + private: |
| + UseGrContext(GLRenderer* renderer, DrawingFrame* frame) |
| + : renderer_(renderer), frame_(frame) { |
| + PassControlToSkia(); |
| + } |
| + |
| + void PassControlToSkia() { context()->resetContext(); } |
| + |
| + void PassControlToGLRenderer() { |
| + context()->flush(); |
| + renderer_->RestoreGLState(frame_); |
| + } |
| + |
| + GLRenderer* renderer_; |
| + DrawingFrame* frame_; |
| + DISALLOW_COPY_AND_ASSIGN(UseGrContext); |
|
enne (OOO)
2014/04/23 19:53:41
Stick a blank line before DISALLOW for readability
|
| +}; |
| + |
| struct GLRenderer::PendingAsyncReadPixels { |
| PendingAsyncReadPixels() : buffer(0) {} |
| @@ -300,7 +333,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 +602,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::UseGrContext> 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 +626,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 +651,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 +670,17 @@ 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(); |
| - |
| return device.accessBitmap(false); |
| } |
| static SkBitmap ApplyBlendModeWithBackdrop( |
| - GLRenderer* renderer, |
| - ContextProvider* offscreen_contexts, |
| + scoped_ptr<GLRenderer::UseGrContext> 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 +702,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 +718,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 +764,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,14 +779,6 @@ 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(); |
| - |
| return device.accessBitmap(false); |
| } |
| @@ -847,8 +855,8 @@ scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters( |
| SkBitmap filtered_device_background; |
| if (apply_background_filters) { |
| filtered_device_background = |
| - ApplyImageFilter(this, |
| - frame->offscreen_context_provider, |
| + ApplyImageFilter(UseGrContext::Create(this, frame), |
| + resource_provider_, |
| quad->rect.origin(), |
| filter.get(), |
| device_background_texture.get()); |
| @@ -959,8 +967,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,8 +984,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
| // in the compositor. |
| use_color_matrix = true; |
| } else { |
| - filter_bitmap = ApplyImageFilter(this, |
| - frame->offscreen_context_provider, |
| + filter_bitmap = ApplyImageFilter(UseGrContext::Create(this, frame), |
| + resource_provider_, |
| quad->rect.origin(), |
| filter.get(), |
| contents_texture); |
| @@ -990,8 +996,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(UseGrContext::Create(this, frame), |
| + resource_provider_, |
| filter_bitmap, |
| contents_texture, |
| background_texture.get(), |
| @@ -3131,6 +3137,41 @@ void GLRenderer::ReinitializeGLState() { |
| scissor_rect_needs_reset_ = true; |
| } |
| +void GLRenderer::RestoreGLState(DrawingFrame* frame) { |
|
enne (OOO)
2014/04/23 19:53:41
How does this function compare to ReinitializeGLSt
danakj
2014/04/23 19:56:05
It's similar but
1. It doesn't change any state o
enne (OOO)
2014/04/23 20:01:10
I think you should combine these if possible. I t
danakj
2014/04/23 20:11:10
I can give merging them a try again.
|
| + 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_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
| + GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0)); |
| + |
| + if (stencil_shadow_) |
|
Stephen White
2014/04/23 19:57:20
I'm a little nervous that this state-setting code
|
| + 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)); |
| + } |
| + |
| + SetUseProgram(0); |
| + |
| + UseRenderPass(frame, frame->current_render_pass); |
| +} |
| + |
| bool GLRenderer::IsContextLost() { |
| return output_surface_->context_provider()->IsContextLost(); |
| } |