Closed libaineu2004 closed 4 years ago
By the way, my computer's opengl environment configuration is correct, the computer can run other opengl-related programs normally.
You should be able to debug through the creation of your glInterface
and the context
objects and see exactly what is wrong. Skia does not set up everything required for it to use OpenGL itself: it expects OpenGL to be initialized (skui::gui::native_visual
contains some Windows code that does at least part of this). Your best bet is to step into the GrContext::MakeGL
and see what exactly is going wrong. Note I only ever tested my Windows GL with the Mesa software implementation. It's highly likely this code doesn't set up the proper OpenGL context required by Skia and Mesa is just giving me a sensible default that is enough for Skia, where other graphics drivers might not. Now that I think about it, this fact may explain people not being able to use SkUI with OpenGL on Windows (see #11). If this would be the case, you'd see Skia checking for various OpenGL features it needs and one of them will fail due to a bad OpenGL context version being used.
SkUI's 3rdparty repository contains unmodified Google Skia source code (currently branch m83), but is built through my handmade CMakeLists.txt to not have to interface with GN or whatever other build system Google dreams up to build Skia with in the future. As far as I could tell when I first created my CMakeLists.txt, there's no special build options in the original Skia build system that seem to matter.
@rubenvb
I compiled the example widget_gallery.exe that comes with skui. Enable F5 breakpoint entry, First reach the source file:
skia_gl_context :: skia_gl_context (gr_gl_get_function get_function) : context {} , gr_gl_interface {GrGLAssembleInterface (nullptr, get_function)} { SkASSERT (get_function); SkASSERT (gr_gl_interface); // error here }
Finally reach the source file: skia \ skui \ 3rdparty \ skia \ src \ gpu \ gl \ GrGLAssembleInterface.cpp In the end I found that the "nullptr == GetString" condition is true.
define GET_PROC_LOCAL (F) GrGL ## F ## Fn F = (GrGL ## F ## Fn ) get (ctx, "gl" #F)
sk_sp
GrGLMakeAssembledInterface (void * ctx, GrGLGetProc get) { GET_PROC_LOCAL (GetString); // error here if (nullptr == GetString) { return nullptr; } }
The implication is to say GrGLGetStringFn GetString = (GrGLGetStringFn ) get (ctx, "glGetString"); The value of GetString is nullptr;
so I get: gr_gl_interface = nullptr;
Why? Does the function glGetString not exist?
What it's doing here is calling the get
function, for which I picked the same logic as the one used by Skia, which is also what the OpenGL wiki says to do. The one SkUI uses on Windows is located here. I used skui::core::library
which in the end calls GetProcAddress instead of direcly loading the opengl32 library directly.
Could you try replacing the get_gl
function in wgl.c++
with Skia's simpler version directly and see if that works?
Ah wait never mind I see the problem. skui::core::library::load
is trying to be smart but in reality isn't.
I pushed an update to master which should let skui::core::library::load
do the correct thing.
@rubenvb It may not be a skui problem, but a sklib problem. I created a minimal demo.
"sk_sp
What steps will reproduce the problem? SkSurface::MakeRenderTarget returned null
What is the expected output? What do you see instead?
sk_sp
What version of the product are you using? On what operating system? skia-m83/Win7 x64/MSVC 2017/NVIDIA GeForce GT 630
Please submit a code sample. void draw(SkCanvas *canvas) { canvas->drawColor(SK_ColorWHITE); SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setAntiAlias(true); paint.setStrokeWidth(4); paint.setColor(0xff4285F4); SkRect rect = SkRect::MakeXYWH(10, 10, 100, 160); canvas->drawRect(rect, paint); SkRRect oval; oval.setOval(rect); oval.offset(40, 80); paint.setColor(0xffDB4437); canvas->drawRRect(oval, paint); paint.setColor(0xff0F9D58); canvas->drawCircle(180, 50, 25, paint); rect.offset(80, 50); paint.setColor(0xffF4B400); paint.setStyle(SkPaint::kStroke_Style); canvas->drawRoundRect(rect, 10, 10, paint); }
void gl_example(int width, int height, void (draw)(SkCanvas ), const char path)
{
// You've already created your OpenGL context and bound it.
sk_sp
int main(int argc, char *argv[]) { gl_example(300, 300, draw, "d:\demo3.jpg"); return 0; }
void gl_example(int width, int height, void (*draw)(SkCanvas *), const char *path) { // You've already created your OpenGL context and bound it. sk_sp interface = nullptr; // Leaving interface as null makes Skia extract pointers to OpenGL functions for the current // context in a platform-specific way. Alternatively, you may create your own GrGLInterface and // initialize it however you like to attach to an alternate OpenGL implementation or intercept // Skia's OpenGL calls. **sk_sp context = GrContext::MakeGL(interface);//error here** /* ~SNIP~ */ int main(int argc, char *argv[]) { gl_example(300, 300, draw, "d:\demo3.jpg"); return 0; }
You are immediately calling GrContext::MakeGL
expecting it to work, but it doesn't. You first need to set up a proper OpenGL context yourself (I believe Skia needs OpenGL 2.1 at the very least) . This happens in SkUI code in the native_visual
subclasses, which are responsible for setting up the underlying state of the graphics stuff to draw on screen.
Note again that on Windows, it does not do the right thing, and it only sort of works with the Mesa software GL implementation in its current form.
This project is not the right place to ask help with the Skia library. It only uses it to do the actual drawing. Skia have a nice community here: https://groups.google.com/forum/#!forum/skia-discuss. Feel free to use my Skia 3rdparty setup, but I can't help you set up Skia for you purposes. If you have questions about SkUI code, feel free to ask me, but not through the issues here.
==========Win7 x64/MSVC 2017==========
My code is: void QSkiaOpenGLWidget::initializeGL() { initializeOpenGLFunctions(); sk_sp glInterface = nullptr;
sk_sp context = nullptr;
context = GrContext::MakeGL(glInterface);
SkASSERT(context); //error here
}
//context will be equal to null, SkASSERT () will throw an exception!
Is there any problem with the skia library included in the skui project? Is it the same as Google's official source code and compilation options?